我有ProductPrice,产品和菜单
产品belongs_to菜单和ProductPrice到产品。
我通过cocoon嵌套对象一次性创建产品价格。
在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属性,并且始终使用填充的menu_id创建Product。
答案 0 :(得分: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
不会发生或处理。此外,可以添加验证以确保ProductPrice
在创建每个对象时与Product
有关联。
class ProductPrice < ActiveRecord::Base
belongs_to :product
validates :product, :presence => true
def menu
product.menu
end
end
答案 1 :(得分:0)
必须将def菜单更改为:
def menu
if !self.product.nil?
self.product.menu
end
end
答案 2 :(得分:0)
我遇到了与has_one / belongs_to关系类似的问题,其中每个关系都验证了另一个的存在。特别是在测试代码中,这使得在没有绕过验证或溢出堆栈的情况下存根其中一个是一个挑战。
解决方案是:
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
忽略允许您在要测试验证代码时覆盖。
更好的设计方法是将它全部放在一个表中,但不幸的是,它是一个遗留数据库。
答案 3 :(得分:0)
我将从上面的答案中采用以下模型设置作为示例
class Menu < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :menu
has_one :product_price
end
现在,就像它一样简单,您只需要在菜单和产品类的关联中添加:inverse_of
,如下所示:
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