我正在编写一个简单的会计系统来管理成本。结构是这样的:
Invoice - can have many products
Product - can have many costs, also can act_as_tree
LineItem -
Product
LineItem
LineItem
Product
LineItem
Product
LineItem
LineItem
我将这个设置为三个类的has_many和belongs_to但是认为以下更合适(基于阅读Rails 3 Way - 任何缺点是我缺乏理解;只是尝试给出上下文)
Class Invoice < ActiveRecord::Base
has_many :products
has_many :line_items, :through => :products
end
Class Product < ActiveRecord::Base
belongs_to :invoice
belongs_to :line_item
end
class LineItem < ActiveRecord::Base
has_many :products
has_many :invoices, :through => :invoices
end
但我不这样做是正确的。
如果我执行以下操作:
>@i=Invoice.find(1)
>@i.products # this works
>@i.line_items # doesn't work, unidentified method line_items
这是我第一次使用has_many:through。这是否为我的数据模型设置正确?此外,是否可以将其与acts_as_tree结合使用 - 我希望能够说:
>@i.line_items
并取回该特定发票的所有订单项。可能的?
请求帮助
答案 0 :(得分:1)
首先提出一个问题:Product
和LineItem
之间的关系是什么:1个产品有多个订单项,或者是1和许多产品中引用的相同订单项?本答案的其余部分基于每个产品应该有多个订单项的假设。
我认为你的模型应该这样定义:
# No change
Class Invoice < ActiveRecord::Base
has_many :products
has_many :line_items, :through => :products
end
# Changed the relation to :line_items
Class Product < ActiveRecord::Base
belongs_to :invoice
has_many :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :products
# The following then does not make sense
##has_many :invoices, :through => :invoices
end
答案 1 :(得分:1)
你为什么选择这种结构?在这种情况下,我通常做
Class Invoice < ActiveRecord::Base
has_many :line_items
has_many :products, :through => :line_items
end
Class Product < ActiveRecord::Base
has_many :line_items
# if you need
has_many :products, :through => :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :products
belongs_to :invoice
end
满足以下要求:
发票和产品具有Many2Many关系 发票和产品之间的关系是一个LineItem,它提供更多信息,如价格,金额,应用税等。 您可以通过添加Product:
来创建LineIteminvoice = Invoice.create
invoice.products << Product.find_by_name('awesome')
答案 2 :(得分:0)
您的发票只应包含订单项!这些可以是树形结构,但您不应该直接从发票中引用产品(如果产品价格发生变化,这会影响现有的发票!)
所以,要修复你的结构:
invoice
line_item # references a product, but has its own fields (price!)
line_item
line_item
每个line_item
都应使用belong_to
引用一个产品。这是发票和产品之间的联合模式:
class Invoice
has_many :line_items
end
class LineItem
belongs_to :invoice
belongs_to :product
acts_as_tree # (implies has_many :line_items with the parent invoice_id, etc.)
end
class Product
has_many :line_items
end
这基本上就是建立发票所需的全部内容。您可以将树结构视为独立于Invoice:LineItem:Product
关系。它可以作为一个平面列表,或者增强成为一个树。
如果您的产品通常包含其他产品,并且您需要知道在添加父产品时将哪些子项添加到发票中(作为行项目),您还需要对产品进行树形化:
class Product
has_many :line_items
acts_as_tree
end
此树结构独立于订单项中的树结构。请记住:产品可能会发生变化,这不会影响发票中的现有订单项。