我有3张属于同一货件的发票。创建的第一张发票始终是货件的主发票。
Invoice
id shipment_id
21 55 # This is the main invoice
88 55
93 55
如果我执行以下查询
s = Shipment.find(55)
s.invoices[0] # 21
s.invoices[1] # 88
s.invoices[2] # 93
所以我猜测子元素的顺序是由他们的id决定的。我对吗?或者还有更多的东西吗?
我问,因为我需要确定子元素的顺序,以确保我的一个方法始终有效。
def am_i_the_main_invoice?
if self.shipment.invoices[0].id == self.id
true
else
false
end
end
答案 0 :(得分:2)
除非您明确设置,否则订单是随机的。虽然您的数据库现在可能会以相同的顺序返回元素,但如果您更改任何内容(即使看似无关的内容),它也可以是任何其他顺序。所以再次:不要相信从关系数据库中检索的元素的顺序,除非您在查询中明确设置了顺序。
在您可能已设置Shipment
关系的has_many
课程中,您可以添加:order => "id ASC"
之类的内容,以便始终按ID强制执行订单。
答案 1 :(得分:1)
您可以向invoices
表添加标记,而不是依赖于有序查询:
# in migration
add_column :invoices, :is_primary, :boolean, {null: false, default: false}
# if your rdbms supports partial indexes, you can enforce it
execute 'create unique index uniq_single_primary on invoices (shipment_id) where is_primary = true'
# then query is easy ..
def am_i_the_main_invoice?
self.is_primary?
end
答案 2 :(得分:1)
返回的顺序通常取决于您正在使用的SQL数据库。通常它基于主键,但正如Holger Just所说,不要相信它,因为它可以改变。
您可以通过两种方式解决此问题:
scope :by_shipment, order("id ASC")
default_scope order("id ASC")
希望这有帮助
答案 3 :(得分:1)
为了便于阅读,我会添加一个关联扩展名
class Shipment < ActiveRecord::Base
has_many :invoices do
def main
@main_invoice ||= first(:order => "id ASC")
end
def main?(id)
main.try(:id) == id
end
end
end
现在您可以按如下方式获取主发票:
shipment.invoices.main # returns main invoice
shipment.invoices.main?(23) # checks if the invoice is a main invoice
通过这种方式,您可以清楚地了解main
发票的概念。