I'm trying to create a form which allows me to submit new records for an association where the association inputs are grouped.
class Product < AR::Base
has_many :properties
accepts_nested_attributes_for :properties
end
Note that in the controller a series of properties are built for the product, so @product.properties.empty? # => false
.
The below fields_for
gives me the correct inputs with names such as product[properties_attributes][0][value]
.
= form.fields_for :properties do |pform|
= pform.input :value
But as soon as I try and group the association it no longer generates inputs with the correct names:
- @product.properties.group_by(&:group_name).each do |group_name, properties|
%h3= group_name
= form.fields_for properties do |pform|
= pform.input :value
This create inputs which the name
attribute like product[product_property][value]
when in fact it should be product[property_attributes][0][value]
as per the first example.
The Rails documentation suggests you can do this:
= form.fields_for :properties_attributes, properties do |pform|
But this gives an error "undefined method value for Array".
You need to set up like this:
- @product.properties.group_by(&:group_name).each do |group_name, properties|
%h3= group_name
= form.fields_for :properties, properties do |pform|
= pform.text_field :value
It should work fine, since you have accepts_nested_attributes_for :properties
rails know that it's supposed to create fields for properties_attributes
. Moreover you may want to add
attr_accessible :properties_attributes
if you are using one of newest Rails and if you didn't add it to your model yet ;)
Also, if you want to make some decision base on single property you may use the following form as well:
- @product.properties.group_by(&:group_name).each do |group_name, properties|
%h3= group_name
- properties.each do |property|
= form.fields_for :properties, property do |pform|
= pform.text_field :value
Both of them are nicely described here: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for under One-To-Many
section
I don't know of a clean 'Rails' solution to this sort of thing, but I often handle these types of situations more manually. eg - Loop through the groups and conditionally show only those properties that are in a particular group.
class Product < AR::Base
has_many :properties
accepts_nested_attributes_for :properties
def group_names
properties.map(&:group_name).uniq.sort
end
end
In the view
- for group_name in product.group_names
= form.fields_for :properties do |pform|
%h3= group_name
- if pform.object.group_name.eql?(group_name)
= pform.input :value
There may be a little overhead with this, getting the list of properties from product repeatedly. You may be able to modify your has_many :properties association to retrieve the properties in group_name order - then you could add the %h3 when it's a new group.
- previous_group_name = nil
= form.fields_for :properties do |pform|
- if pform.object.group_name != previous_group_name
%h3= pform.object.group_name
= pform.input :value
- previous_group_name = pform.object.group_name
Some ideas for you...
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