【问题标题】:Preload with limit rails带限位导轨的预载
【发布时间】:2019-02-14 07:45:10
【问题描述】:

如何在 Rails 中预加载具有限制的关联?

例如:

class Comment < ActiveRecord::Base
 belongs_to :post
end

class Post < ActiveRecord::Base
 has_many :comments
end

这很好用:

Post.all.preload(:comments)

但是我如何才能为每个帖子只预加载 一个 评论。 (理想情况下,每个帖子都有一个随机评论)

类似这样的:

Post.all.preload(:comments.limit(1))

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord


    【解决方案1】:

    您可以在下面创建自定义关联,顺序为随机且限制为 1 注意:如果你使用 mysql 将 RANDOM() 更改为 RAND()

    class Post < ActiveRecord::Base
     has_many :comments
     has_one  :random_comment, -> { order("RANDOM()").limit(1) }, class_name: "Comment"
    end
    

    那你就可以了

    Post.all.preload(:random_comment)
    

    【讨论】:

    • 别忘了通过post.random_comment 访问它。如果你打电话给post.comments,它仍然会产生一个 1+N 查询。
    • 您应该放弃.limit(1),因为拥有has_one 关联已经建立了这一点。
    • 我使用 has_one :random_comment, class_name: "Comment" 但我有 Post Load (0.8ms) SELECT "posts".* FROM "posts" ↳ app/views/ posts/index.html.erb:16 评论加载 (96.9ms) SELECT "cmets".* FROM "cmets" WHERE "cmets"."post_id" IN (?, ?, ?, ?, ?, ?, ?) [ ["post_id", 53], ["post_id", 54], ["post_id", 55], ["post_id", 56], ["post_id", 57], ["post_id", 58], [" post_id", 59]] ↳ app/views/posts/index.html.erb:16 与 ** Post.all.preload(:cmets)** 一样,但我们只显示一条评论
    • @SerhiiDanovskyi ^ 流行测验。您将使用什么 SQL 查询在一个查询中获取每个帖子的一条评论? (假设您已经拥有这些帖子。)
    • 我给了你一些思考的时间。 Rails 请求所有 cmets(对于每个帖子)的原因是查询很难生成。从检索到的记录中,只有每个帖子的第一个被实例化。看看这个问题:stackoverflow.com/questions/3800551/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 2011-08-02
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    相关资源
    最近更新 更多