Ruby on rails 如何确定关联中的第一个子元素?
我有3张发票属于同一批货。创建的第一张发票始终是装运的主发票Ruby on rails 如何确定关联中的第一个子元素?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有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决定的。我说得对吗?或者还有其他的吗 我这样问是因为我需要确定子元素的顺
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
除非明确设置顺序,否则顺序是随机的。虽然您的数据库现在可能会以相同的顺序返回元素,但如果您更改了任何内容(甚至是看起来不相关的内容),它可以是任何其他顺序。所以再次强调:不要信任从关系数据库检索的元素的顺序,除非您在查询中显式地设置了顺序
在您的
shipping
类中,您可能已经设置了一个具有多个关系,您可以添加类似:order=>“id ASC”
的内容,以始终按id强制执行订单。除非您明确设置,否则订单是随机的。虽然您的数据库现在可能会以相同的顺序返回元素,但如果您更改了任何内容(甚至是看起来不相关的内容),它可以是任何其他顺序。所以再次强调:不要信任从关系数据库检索的元素的顺序,除非您在查询中显式地设置了顺序
在您的shipping
类中,您可能已经设置了一个有许多关系,您可以添加类似:order=>“id ASC”
的内容,以始终按id强制执行订单。您可以向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
您可以在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
返回的顺序通常取决于您使用的SQL数据库。通常它是基于主键的,但正如前面所说的,不要相信它,因为它可以更改
您可以通过两种方式解决此问题:
在您的发票模型中添加一个范围,您可以在查看您的收款之前调用该范围,例如范围:按装运、订单(“id ASC”)
添加默认范围,以便始终按该顺序检索,例如default\u范围顺序(“id ASC”)
希望这有帮助返回的顺序通常取决于您使用的SQL数据库。通常它是基于主键的,但正如前面所说的,不要相信它,因为它可以更改
您可以通过两种方式解决此问题:
在您的发票模型中添加一个范围,您可以在查看您的收款之前调用该范围,例如范围:按装运、订单(“id ASC”)
添加默认范围,以便始终按该顺序检索,例如default\u范围顺序(“id ASC”)
希望这有帮助为了可读性,我会添加一个关联扩展
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
这样,您就清楚地公开了main
invoice的概念 为了可读性,我会添加一个关联扩展
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
这样,您就清楚地公开了main
invoice的概念 我不得不修改查询,因为我不断地得到错误,所以这就是main\u invoice
方法中的内容:self.invoices(:order=>'id ASC')。首先。我喜欢这种方法,因为它不需要更改数据库。错误是什么?另外,我认为发票(:order=>'id ASC')
不会修改排序顺序。关联方法采用boolean
参数来重新加载关联数组。我会先使用self.order(“id ASC”)。我使用了我给出的代码,以前它对我很有效。我不得不修改查询,因为我不断出错,所以这就是main\u invoice
方法中的内容:self.invoices(:order=>'id ASC')。首先。我喜欢这种方法,因为它不需要更改数据库。错误是什么?另外,我认为发票(:order=>'id ASC')
不会修改排序顺序。关联方法采用boolean
参数来重新加载关联数组。我会先使用self.order(“id ASC”)。我使用过我给出的代码,它以前也为我工作过。只有在某些数据库(例如MySQL)中,当不指定顺序时,您通常会获得按primar键排序的数据。然而,即使是MySQL有时也会返回无序数据(例如在压缩之后)。其他数据库(如Postgres)更频繁地返回有序数据。一般来说(根据各种SQL标准),如果没有指定顺序,它可能是随机的。@HolgerJust我个人总是设置一个顺序,除非我不在乎,因为你是对的,甚至MySQL也会使它们无序。从我所看到的情况来看,SQLite似乎也把它们按顺序带了出来。但宁可安全也不要后悔,对吧;)只有在某些数据库(例如MySQL)中,在不指定顺序的情况下,您通常会获得按primar键排序的数据。然而,即使是MySQL有时也会返回无序数据(例如在压缩之后)。其他数据库(如Postgres)更频繁地返回有序数据。一般来说(根据各种SQL标准),如果没有指定顺序,它可能是随机的。@HolgerJust我个人总是设置一个顺序,除非我不在乎,因为你是对的,甚至MySQL也会使它们无序。从我所看到的情况来看,SQLite似乎也把它们按顺序带了出来。但宁可安全也不要后悔,对吧;)