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