Rails 从关联中获取所有内容,包括最后一行

Sen*_*hil 1 ruby-on-rails associations eager-loading ruby-on-rails-4

我有两个模型,其中 has_many 属于关系。

Scheme has_many navs
Run Code Online (Sandbox Code Playgroud)

我需要获取仅具有最后导航值的所有方案。我有 10 个方案,每个方案都有大约 100k 导航,但我只需要最后一条记录,即当前值。

通过急切加载将加载所有导航

Scheme.all.includes(:navs)
Run Code Online (Sandbox Code Playgroud)

如何在急切加载时应用条件以仅获取每个方案的最后一行导航。

使用日志更新

如果我跑

Scheme.includes(:current_nav).limit(3)
Run Code Online (Sandbox Code Playgroud)

这些是 AR 执行的查询

SELECT  `schemes`.* FROM `schemes`  LIMIT 3
SELECT `navs`.* FROM `navs`  WHERE `navs`.`schemeCode` IN ('D04', 'D01', 'D30')  ORDER BY id DESC
Run Code Online (Sandbox Code Playgroud)

第二个查询是如何工作的,它将获取所有其 schemaCode 属于 list 的导航,并按 id DESC 对它们进行排序,但它将如何与特定方案精确关联。

Sur*_*rya 5

创建另一个这样的关联怎么样:

class Scheme < ActiveRecord::Base
  has_one :current_nav, -> { order('id DESC').limit(1) }, class_name: 'Nav'
end
Run Code Online (Sandbox Code Playgroud)

现在你可以:

Schema.includes(:current_nav).all
Run Code Online (Sandbox Code Playgroud)

或者:

Schema.includes(:current_nav).last(10)
Run Code Online (Sandbox Code Playgroud)

将只急切加载查询方案的最后一个导航。

说明includes是从数据库中检索对象的方法之一ActiveRecord。来自文档本身:

Active Record 允许您提前指定要加载的所有关联。这可以通过指定 Model.find 调用的 contains 方法来实现。通过包含,Active Record 可确保使用尽可能少的查询来加载所有指定的关联。

而且,由于我们已经与 建立了关联current_nav,所以我们所要做的就是使用它来includes预先加载数据。请阅读ActiveRecord 查询文档以获取更多信息。

  • @Senthil:添加了解释,我很高兴您的问题得到了解决。我想我不需要这么说,但是由于我对SO上的OP感到不知所措,即使它有帮助,也不接受答案,所以,如果他们解决了你的问题,请接受你在SO上的问题的答案。祝你编程愉快。 (2认同)