我正在尝试创建一个表单,允许我为关联输入分组的关联提交新记录。
class Product < AR::Base
has_many :properties
accepts_nested_attributes_for :properties
end
请注意,在控制器中为产品构建了一系列属性,因此@product.properties.empty? # => false
。
以下fields_for
为我提供了正确的输入,其名称为product[properties_attributes][0][value]
。
= form.fields_for :properties do |pform|
= pform.input :value
但是一旦我尝试对关联进行分组,它就不再生成具有正确名称的输入:
- @product.properties.group_by(&:group_name).each do |group_name, properties|
%h3= group_name
= form.fields_for properties do |pform|
= pform.input :value
根据第一个示例,这创建name
属性(如product[product_property][value]
的输入,实际上它应该是product[property_attributes][0][value]
。
Rails文档建议您可以这样做:
= form.fields_for :properties_attributes, properties do |pform|
但是这给出了一个错误“Array的未定义方法值”。
答案 0 :(得分:6)
您需要设置如下:
- @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
它应该可以正常工作,因为你知道accepts_nested_attributes_for :properties
rails应该为properties_attributes
创建字段。此外,您可能想要添加
attr_accessible :properties_attributes
如果您使用的是最新的Rails之一,并且尚未将其添加到模型中;)
此外,如果您想根据单一属性做出一些决定,您也可以使用以下表格:
- @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
这里很好地描述了它们:One-To-Many
部分下的http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
答案 1 :(得分:1)
我不知道这种事情的干净'Rails'解决方案,但我经常手动处理这些类型的情况。例如 - 循环遍历组并有条件地仅显示特定组中的属性。
class Product < AR::Base
has_many :properties
accepts_nested_attributes_for :properties
def group_names
properties.map(&:group_name).uniq.sort
end
end
在视图中
- 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
这可能会有一点开销,反复从产品中获取属性列表。您可以修改has_many:properties关联以检索group_name顺序中的属性 - 然后您可以在它是新组时添加%h3。
- 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
有些想法......