15

私は次のモデルを持っています

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のソリューションははるかにエレガントであり、私よりも優先されるべきです。

4

2 に答える 2

24

: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

現在のプロジェクトでは、このコードは正常に機能しています。

より良い解決策を見つけたら教えてください。

于 2011-05-03T14:04:22.847 に答える
2

同じ問題が発生し、ネストされたパラメータリストに:idを追加することで解決しました。

def family_params
  params.require(:family).permit(:user_id, :address, people_attributes: [:id, :relation, :first_name, :last_name)
end
于 2016-03-14T03:10:41.257 に答える