accepts_nested_attributes_for链接到现有记录,而不创建新记录 [英] accepts_nested_attributes_for to link to existing record, not create a new one

查看:77
本文介绍了accepts_nested_attributes_for链接到现有记录,而不创建新记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下型号

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

现在,我有一个订单视图,我想在此更新产品商店. 事实是,我只想将产品连接到数据库中的现有商店,而不创建新商店.

Now I have a order view where I want to update the shops for the product. The thing is that I only want to connect the products to the existing shops in my db, not create new ones.

我的订单视图中的表单如下(使用Formtastic):

My form in the order view looks like this (using 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会尝试使用该名称创建一个新商店.我希望它仅使用现有商店并将产品连接到该商店.

Although its nested it works fine. The problem is that, when I select a store and try to update the order (and the products and stores with it), Rails tries to create a new store with that name. I want it to just use the existing store and connect the product to that.

任何帮助表示赞赏!

最后,我以一种非常粗糙的方式解决了这个问题:

In the end I solved this problem in a very crude way:

# 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

Pablo的解决方案更加优雅,应该比我的首选.

Pablo's solution is much more elegant and should be preferred over mine.

推荐答案

尝试实现:reject_if来检查商店是否已经存在,然后使用它:

Try to implement a :reject_if that check if the Store already exists and then use it:

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

我的这段代码在当前项目中工作正常.

I have this code working fine in a current project.

请,如果您找到更好的解决方案,请告诉我.

Please, let me know if you found a better solution.

这篇关于accepts_nested_attributes_for链接到现有记录,而不创建新记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆