我一直在寻找最好的方法来做到这一点已经有一段时间了,但结果平平,所以我决定在这里提问。
场景如下:我有三个模型,任务、用户和评论,基本上如下所示:
class Task < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :task
end
class User < ActiveRecord::Base
has_many :tasks
has_many :comments
end
我正在尝试输出一个任务列表(就这个问题而言,假设是最后 10 个任务),并将每个任务的最后评论及其作者(用户模型)与 >尽可能减少查询。
谢谢
更新:我结合了 Blue Smith 和 harigopal 的解决方案,因此解决方案如下所示:
class Task < ActiveRecord::Base
belongs_to :user
has_many :comments
has_one :last_comment, -> { order 'created_at' }, class_name: "Comment"
end
然后获取这样的评论:
tasks = Task.joins(last_comment: :user)
.includes(last_comment: :user)
.order('tasks.created_at DESC').limit(10).load
它只产生一个查询,这正是我正在寻找的!谢谢!
最佳答案
您必须连接表,并预先加载数据以最大限度地减少查询数量。
例如:
tasks = Task.joins(comments: :user)
.includes(comments: :user)
.order('tasks.created_at DESC')
.limit(10).load
comments = tasks.first.comments # No query, eager-loaded
user = comments.first.user # No query, eager-loaded
这应该会将查询数量减少到只有一个(非常复杂的查询),因此您必须确保索引符合标准! :-D
关于组合联接和包含的官方文档含糊不清,但应该有所帮助:http://guides.rubyonrails.org/active_record_querying.html#joining-multiple-associations
编辑:
这是一个演示应用程序,其模型与您使用上述方法执行预加载的模型相同。它使用两个查询来加载数据。启动应用程序以查看其运行情况。
https://github.com/harigopal/activerecord-join-eager-loading
关于ruby-on-rails - 获取 Rails 中最后的相关记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17501742/