Rails Active Record:与:order和:group一起查找

我有一个像这样的结构:

class User has_many :dongles has_many :licences, :through => :dongles end class Dongle has_many :licences belongs_to :user end class Licence belongs_to :dongle end 

但是,时间过去了,用户最终会获得每个加密狗的多个许可证。 合理地,该应用程序想要总结每个许可证的最新许可证。

我知道我可以天真地这样做:

 user.dongles.each do |dongle| licence = dongle.licences.find(:first, :order => 'created_at DESC') # do something with the licence info end 

但有没有办法通过集合来做到这一点,并避免通常通过天真的方式做出的大量查询?

我试过这个:

 user.licences.find(:all, :order => 'created_at DESC', :group => 'dongle_id') 

这确实为每个加密狗返回一个许可证,但它所采用的第一个许可证由“id”决定, 而不是由我在查询中指定的顺序决定。

有没有办法我可以让它给我第一个,使用我提供的排序顺序来决定哪个是第一个?

从您的模型中,已经声明了所有关联信息。 通过使用ActiveRecord include选项执行单个查询,您实际上可以使用每个用户来访问加密狗和许可证信息。

 # Say the table name is licences and dongles. users = User.find(:all, :include => [:dongles, :licences], :order => "licences.created_at DESC, dongles.created_at DESC") 

我假设您要创建每个用户拥有的每个加密狗的最新许可证摘要。 您可以根据实际需要减少循环。

 users.each do |user| # do something with your user info user.dongles.each do |dongle| # do something with your dongle info licence = dongle.licences.first # do something with the licence info end end 

有关详细信息,请访问http://snippets.dzone.com/posts/show/2089

您是否尝试过默认范围? 首先,您可以尝试在has_many中添加订单,就像我在用户中显示的那样。

 class User has_many :dongles has_many :licences, :through => :dongles, :order => 'created_at DESC' end 

但是,我不确定这是否真的适用于has-many-through关联,也许,如果这不起作用,您可以尝试将其添加到Dongle中的关联。

 class Dongle has_many :licences, :order => 'created_at DESC' belongs_to :user end 

第二种选择是尝试使用我在许可证中显示的默认范围。

 class Licence default_scope :order => 'created_at DESC' belongs_to :dongle end 

之后,用user.licenses.find(:first)获取它应该足够了