Rails带有check_box循环的嵌套属性

时间:2014-05-02 01:56:55

标签: ruby-on-rails ruby nested-attributes

所以我有一个类别模型

class Category < ActiveRecord::Base
has_many :provider_categories
has_many :providers, :through => :provider_categories
end

和提供者模型

class Provider < ActiveRecord::Base
has_many :provider_categories
has_many :categories, :through => :provider_categories

accepts_nested_attributes_for :provider_categories, :allow_destroy => true
end

这是我的provider_category模型

class ProviderCategory < ActiveRecord::Base
belongs_to :provider
belongs_to :category
end

我试图创建一个嵌套表单,将类别包含在提供者表单中

= form_for @provider do |f|
  ...
  -@categories.each.with_index do |category,index|
    =f.fields_for :provider_category, category do |pl|
      =pl.check_box :category_id
      =pl.label category.name
      =pl.hidden_field :provider_id, value: @provider.id

当我加载页面时,复选框不合作

undefined method `category_id' for #<Category:0x0000010184ff60>

修改

如果我将:category_id更改为id它可以工作,但html outpuy看起来像这样

<input name="provider[provider_category][id]" type="hidden" value="0"><input checked="checked" id="provider_provider_category_id" name="provider[provider_category][id]" type="checkbox" value="1">
<label for="provider_provider_category_Acupuncture">Acupuncture</label>
<input id="provider_provider_category_provider_id" name="provider[provider_category][provider_id]" type="hidden" value="1">

编辑2:

我最终使用了check_box_tag

-@categories.each.with_index do |category|
  =f.fields_for :provider_category, category do |pl|
    .li
      =check_box_tag "provider[provider_category][category_id]", category.id
      =pl.label category.name
      =pl.hidden_field :provider_id, value: @provider.id

现在html输出似乎是正确的,但它没有保存它。当我选择多个项目时,这是保存的哈希值

"provider"=>{"name"=>"Mr. Awesome", "phone"=>"999-999-9999", "email"=>"awesome@awesome.com", "address"=>"awesome land", "provider_category"=>{"category_id"=>"3", "provider_id"=>"1"}}, "commit"=>"Save", "id"=>"1"}

我确实选择了3个选项,但只将最后一个添加到哈希

我还在提供者控制器的强参数中添加了提供者类别

params.require(:provider).permit(..., :provider_categories => [:category_id, :provider_id])

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

根据您的模型定义,ProviderCategory具有category_idprovider_id属性。你收到的错误是:

undefined method `category_id' for #<Category:0x0000010184ff60>

因为您没有传递ProviderCategory的实例,而是传递了Category类的实例。注意在{/ p>中传递category

=f.fields_for :provider_category, category do |pl|

并且因为模型category_id中没有名为Category的属性,您会收到错误。

要解决此问题,只需在视图中更新fields_for方法调用,如下所示:

=f.fields_for :provider_categories, category.provider_categories.build do |pl|

<强>更新

此外,您必须更新ProvidersController的强参数,以便provider_categories的记录在数据库中正确保存:

params.require(:provider).permit(..., :provider_categories_attributes => [:category_id, :provider_id])

使用provider_categories_attributes而非provider_categories

更新2

OP还有另一个问题,因为未经检查category_id,正在传递值0category_id设置为0的错误记录已在{{1}中创建}。

建议将provider_categories选项传递给reject_if模型中的accepts_nested_attributes_for方法,以拒绝这些记录,如下所示:

Provider

复选框未传递已检查类别的ID,建议更新复选框代码,如下所示:

class Provider < ActiveRecord::Base
  has_many :provider_categories
  has_many :categories, :through => :provider_categories
  accepts_nested_attributes_for :provider_categories, :allow_destroy => true, reject_if: proc { |attributes| attributes['category_id'] == "0" }
end