我的结构是这样的:
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'决定,不是由我在查询中指定的顺序决定。
我有没有办法让它给我第一个,使用我提供的排序顺序来决定哪个是第一个?
答案 0 :(得分:3)
从您的模型中,已经声明了所有关联信息。通过使用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
了解详情
答案 1 :(得分:-1)
您是否尝试过默认范围? 首先,您可以尝试在has_many中添加订单,如我在User中所示。
class User
has_many :dongles
has_many :licences, :through => :dongles, :order => 'created_at DESC'
end
但是,我不确定这是否真的适用于多次通过关联,也许,如果这不起作用,您可以尝试将其添加到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)