0

ProductPrice、Product、Menu があります

製品はメニューに属し、製品価格は製品に属します。

繭のネストされたオブジェクトを使用して、一度に価格で製品を作成しています。

ProductPrice には、次のコードがあります。

def menu
  self.product.menu;
end

価格は、product_category とサイズによって異なります。したがって、新しい製品を作成するとき、ユーザーはその製品が属するカテゴリを選択し、ajax を介して product_prices を取得して、ユーザーがその製品の各サイズの価格を入力できるようにします。価格は次の手順で取得されます。

def self.get_product_prices(category_id, product_id)
  if category_id != "0"
    MenuCategory.find(category_id).product_sizes.map do |size|
      if product_id == "0"
        ProductPrice.new({:product_size_id => size.id })
      else
        ProductPrice.find_or_initialize_by_product_size_id_and_product_id(size.id, product_id)
      end
    end
  end
end

これを作成すると、製品が nil として返されるため、エラーが発生します。永続化されていない製品が属するメニューを取得する方法はありますか? ProductPrice には product_id 属性が入力されており、Product は常に menu_id が入力されて作成されていることがわかります。

4

4 に答える 4

0

それぞれが他の存在を検証する has_one/belongs_to 関係で同様の問題がありました。特にテスト コードでは、これにより、検証をバイパスしたり、スタックをオーバーフローさせたりすることなく、そのうちの 1 つをスタブ化することが困難になりました。

解決策は次のとおりです。

FactoryGirl.define do
  factory :person do
    ignore do
      skip_address false
    end
    after(:build) do |person, evaluator|
      person.address ||= FactoryGirl.build(:address, :person => person) unless evaluator.skip_address
    end
  end
  factory :address do
    ignore do
      skip_person false
    end
    after(:build) do |address, evaluator|
      address.person ||= FactoryGirl.build(:person, :address => address) unless evaluator.skip_person
    end
  end
end

無視を使用すると、検証コードをテストするときにオーバーライドできます。

より良い設計アプローチは、すべてを 1 つのテーブルにすることでしたが、残念ながら、これはレガシー DB です。

于 2013-11-08T14:56:32.390 に答える
0

クラスが次のように定義されていると仮定します。

class Menu < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  belongs_to :menu
  has_one :product_price
end

class ProductPrice < ActiveRecord::Base
  belongs_to :product

  def menu
    product.menu
  end
end

あなたが説明している問題は、製品が実際に割り当てられていない場合にのみ発生する可能性があります。そうは言っても、アプリケーションのどの部分がアクセスproductしているのnilかが発生しないか、適切に処理されないことを確認するために、テストを作成する必要がある場合があります。また、検証を追加しProductPriceProduct、各オブジェクトがいつ作成されるかを確認することもできます。

class ProductPrice < ActiveRecord::Base
  belongs_to :product

  validates :product, :presence => true

  def menu
    product.menu
  end
end
于 2013-05-25T23:24:33.967 に答える
0

例として、上記の回答から次のモデル設定を取り上げます

class Menu < ActiveRecord::Base
  has_many :products
end 

class Product < ActiveRecord::Base
  belongs_to :menu
  has_one :product_price
end    

:inverse_ofそして今、次のように、Menu クラスと Product クラスの関連付けに追加するだけです。

class Menu < ActiveRecord::Base
  has_many :products, inverse_of: :menu
end

class Product < ActiveRecord::Base
  belongs_to :menu, inverse_of: :product
  has_one :product_price
end

そして今、あなたがこのようなことをすると:

menu = Menu.new
product = menu.products.new
product.menu

nilの代わりにメニューオブジェクトを取得します

于 2015-01-18T07:27:44.333 に答える
0

def メニューを次のように変更する必要がありました。

def menu
  if !self.product.nil?
    self.product.menu
  end
end
于 2013-11-08T01:01:07.307 に答える