嵌套属性 + multi select:找不到 ID=["1", "2", "3"] 的集合,用于 ID= 的产品?
nested attributes + multi select: Couldn't find Collection with ID=["1", "2", "3"] for Product with ID=?
我与 collections
有一个多对多的关系,是 product
的多select 字段
products_controller.rb
def new
@product = Product.new
@product.collections.build
@product.categories.build
@product
end
def create
@product = Product.new(product_params)
...
end
private
def product_params
params.require(:product).permit(:product_id, :name, :price, :popularity,
collections_attributes: [ id: [] ])
end
产品型号
class Product < ApplicationRecord
validates :product_id, uniqueness: true
has_and_belongs_to_many :collections, optional: true
accepts_nested_attributes_for :collections, reject_if: ->(attributes){ attributes['id'].blank? }, allow_destroy: true
end
产品浏览
<%= form.fields_for :collections do |fc| %>
<%= fc.label :collections %>
<%= fc.select(:id, Collection.all.collect { |c| [c.name, c.id] },
{ include_blank: true, include_hidden: false }, {multiple: true}) %>
<% end %>
视图将如下所示,因为用户可以选择 select 多个集合
然而,当我post到/create
时,它说
登录 products_params.inspect
不太确定它有什么问题。是因为ids
不能取数组吗?如果是这样,有什么解决方案。
如有任何帮助,我们将不胜感激。谢谢!
更新
整个产品形态。请忽略 product_id
,因为它不是主键。
<%= form_with(model: product, local: true) do |form| %>
<% if product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form.label :product_id %>
<%= form.text_field :product_id %>
<%= form.fields_for :collections do |fc| %>
<%= fc.label :collections %>
<%= fc.select(:id, Collection.all.collect { |c| [c.name, c.id] },
{ include_blank: true, include_hidden: false }, {multiple: true}) %>
<% end %>
<%= form.submit %>
</div>
<% end %>
您不需要嵌套属性来关联记录。这是一个极其普遍的误解。事实上,使用 accepts_nested_attributes_for :collections
会导致您更改 collections
table 而不是 products_collections
加入 table!
而是使用由 has_and_belongs_to_many :collections
创建的 collection_ids=
setter。
class Product < ApplicationRecord
validates :product_id, uniqueness: true
# has_and_belongs_to_many is always optional...
has_and_belongs_to_many :collections
end
<%= form_with(model: product, local: true) do |form| %>
# ...
<div class="field">
<%= form.label :product_id %>
<%= form.text_field :product_id %>
</div>
<div class="field">
<%= f.label :collection_ids %>
<%= f.collection_select(:collection_ids, Collection.all, :id, :name, multiple: true) %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
def product_params
params.require(:product).permit(
:product_id, :name, :price, :popularity,
collection_ids: [] # allows an array of values
)
end
这将根据数组的内容自动 add/delete 连接行。
accepts_nested_attributes_for
仅当您需要在单个表单提交中传递另一个模型(或连接模型)的属性时才需要。 accepts_nested_attributes_for
实际上不能用于为 has_and_belongs_to_many
关联操作联接 table 行,因为没有模型可以接受嵌套属性。您需要改用 has_many through:
。
我与 collections
有一个多对多的关系,是 product
products_controller.rb
def new
@product = Product.new
@product.collections.build
@product.categories.build
@product
end
def create
@product = Product.new(product_params)
...
end
private
def product_params
params.require(:product).permit(:product_id, :name, :price, :popularity,
collections_attributes: [ id: [] ])
end
产品型号
class Product < ApplicationRecord
validates :product_id, uniqueness: true
has_and_belongs_to_many :collections, optional: true
accepts_nested_attributes_for :collections, reject_if: ->(attributes){ attributes['id'].blank? }, allow_destroy: true
end
产品浏览
<%= form.fields_for :collections do |fc| %>
<%= fc.label :collections %>
<%= fc.select(:id, Collection.all.collect { |c| [c.name, c.id] },
{ include_blank: true, include_hidden: false }, {multiple: true}) %>
<% end %>
视图将如下所示,因为用户可以选择 select 多个集合
然而,当我post到/create
时,它说
登录 products_params.inspect
不太确定它有什么问题。是因为ids
不能取数组吗?如果是这样,有什么解决方案。
如有任何帮助,我们将不胜感激。谢谢!
更新
整个产品形态。请忽略 product_id
,因为它不是主键。
<%= form_with(model: product, local: true) do |form| %>
<% if product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form.label :product_id %>
<%= form.text_field :product_id %>
<%= form.fields_for :collections do |fc| %>
<%= fc.label :collections %>
<%= fc.select(:id, Collection.all.collect { |c| [c.name, c.id] },
{ include_blank: true, include_hidden: false }, {multiple: true}) %>
<% end %>
<%= form.submit %>
</div>
<% end %>
您不需要嵌套属性来关联记录。这是一个极其普遍的误解。事实上,使用 accepts_nested_attributes_for :collections
会导致您更改 collections
table 而不是 products_collections
加入 table!
而是使用由 has_and_belongs_to_many :collections
创建的 collection_ids=
setter。
class Product < ApplicationRecord
validates :product_id, uniqueness: true
# has_and_belongs_to_many is always optional...
has_and_belongs_to_many :collections
end
<%= form_with(model: product, local: true) do |form| %>
# ...
<div class="field">
<%= form.label :product_id %>
<%= form.text_field :product_id %>
</div>
<div class="field">
<%= f.label :collection_ids %>
<%= f.collection_select(:collection_ids, Collection.all, :id, :name, multiple: true) %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
def product_params
params.require(:product).permit(
:product_id, :name, :price, :popularity,
collection_ids: [] # allows an array of values
)
end
这将根据数组的内容自动 add/delete 连接行。
accepts_nested_attributes_for
仅当您需要在单个表单提交中传递另一个模型(或连接模型)的属性时才需要。 accepts_nested_attributes_for
实际上不能用于为 has_and_belongs_to_many
关联操作联接 table 行,因为没有模型可以接受嵌套属性。您需要改用 has_many through:
。