Подтвердить что ты не робот

Rails Form Объекты с несколькими вложенными ресурсами

7 Образцы для моделей ActiveRecord для рефакторинга Fat - вот отличная статья о различных подходах рефакторинга с использованием PORO. Под 3-м заголовком есть шаблон формы объекта, который мне очень понравился и уже реализован в одном из проектов. Существует только пример использования одного вложенного ресурса, но я хотел бы реализовать этот шаблон для нескольких вложенных ресурсов. Может быть, кто-то здесь уже справился с этим? Мне не обязательно нужны примеры кода, просто основная идея будет в порядке.

Обновление

Рассмотрим этот пример. У меня две модели.

class Company
  has_many :users

  accepts_nested_attributes_for :users
end

class User
  belongs_to :company
end

В случае одного вложенного пользователя для компании, использующего шаблон формы объекта, я бы написал следующее:

<%= form_for @company_form do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :user_name %>
  <%= f.submit %>
<% end %>     

Объект формы

class CompanyForm
  include Virtus

  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations

  attr_accessor :company, :user

  def user
    @user ||= company.users.build
  end

  def company
    @company ||= Company.new
  end

  def submit(params={})
    company.name = params[:name]
    user.name = params[:user_name]
    persist!
  end

  private

  def persist!
    company.save!
    user.save!
  end
end 

Но что, если у меня есть форма, где можно создать компанию с несколькими пользователями. Обычный подход заключается в том, чтобы написать его так, используя nested_form:

<%= nested_form_for @company do |f| %>
  <%= f.text_field :name %>
  <%= fields_for :users, do |user_form| %>
    <%= user.form.text_field :name %>
  <% end %>
  <%= f.link_to_add "Add a user", :users %>
  <%= f.submit %>
<% end %>

Я спрашиваю, как реализовать этот шаблон объекта формы в этом случае?

4b9b3361

Ответ 1

reils fields_for helper проверяет метод в этом формате: #{association_name}_attributes=

поэтому, если вы добавите этот метод в CompanyForm:

def users_attributes=(users_attributes)
  # manipulate attributes as desired...
  @company.users_attributes= users_attributes
end

def users
  company.users
end

Генераторы fields_for будут генерировать поля вложенных пользователей для CompanyForm, как если бы это была компания. вышесказанное может быть переписано как делегация, поскольку в методах ничего не происходит:

  delegate :users, :users_attributes=, :to => :company, :prefix => false, :allow_nil => false