7 Patterns to Refactor Fat ActiveRecord Models - here is a great article about different refactoring approaches using PORO. Under the 3rd caption there is a Form Object pattern, which I really liked and already implemented in one of the projects. There is only an example using one nested resource, but I would like to implement this pattern for multiple nested resources. Maybe someone here had already dealt with this? I don't necessarily need any code examples, just the basic idea would be fine.
Update
Consider this example. I have two models.
class Company
  has_many :users
  accepts_nested_attributes_for :users
end
class User
  belongs_to :company
end
In case of one nested user for company using Form Object Pattern I would write the following:
<%= form_for @company_form do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :user_name %>
  <%= f.submit %>
<% end %>     
Form Object
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 
But what if I have a form, where a company with multiple users can be created. The usual approach is to write it like this, using 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 %>
What I am asking is how do I implement that Form Object Pattern in this case?
the rails fields_for helper checks for a method in this format: #{association_name}_attributes=
so, if you add this method to CompanyForm:
def users_attributes=(users_attributes)
  # manipulate attributes as desired...
  @company.users_attributes= users_attributes
end
def users
  company.users
end
the fields_for generators will generate the nested users fields for a CompanyForm as if it were a Company. the above could be rewritten as a delegation since nothing is happening in the methods:
  delegate :users, :users_attributes=, :to => :company, :prefix => false, :allow_nil => false
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With