如何急切加载 has_many 关系中的最新对象?

发布于 2024-10-12 14:53:47 字数 425 浏览 3 评论 0原文

我有一个 Rails 3 应用程序,其中包含类别和帖子等模型。

类别

has_many :posts 帖子

属于

_to :category

我希望能够显示类别列表,并在其旁边列出最新的帖子,而无需循环访问每个类别的数据库,并且每个类别只拉回一个帖子。

我想做这个问题提出的同样的事情 - SQL 连接:选择一对多关系中的最后一条记录 - 但希望使用 Active Record。

这是一件愚蠢的事情吗?我是否应该通过急切加载某个类别的所有帖子来撤回它们?我担心性能,这就是我开始研究这个的原因。

I have a rails 3 app that has models like categories and posts.

Category

has_many :posts

Post

belongs_to :category

I want to be able to display a list of categories with the most recent post listed next to it without looping through and hitting the database for each category and only pulling back one post per category.

I want to do the same thing this question poses - SQL join: selecting the last records in a one-to-many relationship - but hopefully using Active Record.

Is this a dumb thing to be doing? Should I just pull back all the posts for a category by eager loading them? I was concerned about performance, which is why I started researching this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

依 靠 2024-10-19 14:53:47

我不确定如果不自己构建查询这是否可行。问题在于,当您开始获得所有条件或试图限制结果时,rails 处理急切加载的方式并不那么好。您可以通过创建另一个关联来使include几乎完成您想要的操作:

class Category < ActiveRecord::Base
  has_one :last_post, :class_name => "Post", :foreign_key => "category_id", :order => "created_at desc"
end

然后您可以正常使用include:

Category.includes(:last_post).all

但是,这样做的问题是,由于生成的sql,它仍然从类别中选择所有帖子,即使当您调用category时也是如此.last_post 它只返回最后一篇文章。它会生成类似这样的sql:

SELECT `categories`.* FROM `categories`
SELECT `posts`.* FROM `posts` WHERE (`posts`.category_id IN (1,2)) ORDER BY created_at desc

I'm not sure if this is possible without building up the query yourself. The problem with this is that the way rails deals with eager loading isn't that good when you start getting at all conditional or trying to limit results. You can make includes nearly do what you want by creating another association:

class Category < ActiveRecord::Base
  has_one :last_post, :class_name => "Post", :foreign_key => "category_id", :order => "created_at desc"
end

Then you can use includes normally:

Category.includes(:last_post).all

But, the problem with this is that because of the sql this generates, it's still selecting all posts from the categories even though when you call category.last_post it returns only the last post. It'll generate sql similar to this:

SELECT `categories`.* FROM `categories`
SELECT `posts`.* FROM `posts` WHERE (`posts`.category_id IN (1,2)) ORDER BY created_at desc
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文