我有以下型号
class Order < AR::Base
has_many :products
accepts_nested_attributes_for :products
end
class Product < AR::Base
belongs_to :order
has_and_belongs_to_many :stores
accepts_nested_attributes_for :stores
end
class Store < AR::Base
has_and_belongs_to_many :products
end
现在我有一个订单视图,我想更新产品的商店。 问题是我只想将产品连接到我的数据库中的现有商店,而不是创建新商店。
订单视图中的我的表单如下所示(使用Formtastic):
= semantic_form_for @order do |f|
= f.inputs :for => :live_products do |live_products_form|
= live_products_form.inputs :for => :stores do |stores_form|
= stores_form.input :name, :as => :select, :collection => Store.all.map(&:name)
虽然它的嵌套工作正常。 问题是,当我选择商店并尝试更新订单(以及产品和商店)时,Rails会尝试创建一个具有该名称的新商店。我希望它只使用现有商店并将产品连接到该商店。
任何帮助表示赞赏!
编辑1:
最后,我以非常粗暴的方式解决了这个问题:
# ProductsController
def update
[...]
# Filter out stores
stores_attributes = params[:product].delete(:stores_attributes)
@product.attributes = params[:product]
if stores_attributes.present?
# Set stores
@product.stores = stores_attributes.map do |store_attributes|
# This will raise RecordNotFound exception if a store with that name doesn't exist
Store.find_by_name!(store_attributes[:name])
end
end
@order.save
[...]
end
编辑2:
Pablo的解决方案更加优雅,应该优先于我的。
答案 0 :(得分:23)
尝试实施:reject_if
,检查商店是否已存在,然后使用它:
class Product < AR::Base
belongs_to :order
has_and_belongs_to_many :stores
accepts_nested_attributes_for :stores, :reject_if => :check_store
protected
def check_store(store_attr)
if _store = Store.find(store_attr['id'])
self.store = _store
return true
end
return false
end
end
我在当前项目中使用此代码。
如果您找到了更好的解决方案,请告诉我。
答案 1 :(得分:0)
我遇到了同样的问题,并通过在嵌套参数列表中添加:id来解决它。
def family_params
params.require(:family).permit(:user_id, :address, people_attributes: [:id, :relation, :first_name, :last_name)
end