Ruby on rails Rails活动记录:与:order和:group一起查找
我有一个类似这样的结构:Ruby on rails Rails活动记录:与:order和:group一起查找,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我有一个类似这样的结构: 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
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
然而,随着时间的推移,用户最终会为每个加密狗获得多个许可证。合理地说,该应用程序希望总结每个应用程序的最新许可证
我知道我可以天真地这样做:
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包含选项执行单个查询,您实际上可以使用每个用户访问加密狗和许可证信息 我假设您希望创建每个用户拥有的每个加密狗的最新许可证摘要。你可以根据你的实际需要来减少这个循环
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
请访问了解更多信息您是否尝试使用默认范围? 首先,您可以尝试在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)
就足够了。这很好,因为它确实减少了查询数量,而代码与我已有的代码没有太大区别(无论如何,它更具可读性)