Rails 预加载和 kaminari

发布于 2024-10-27 19:03:21 字数 1467 浏览 7 评论 0原文

如何在使用 kaminari 分页时使用急切加载?我知道 kaminari 需要 Relation 对象才能工作,如何使用 :include 检索模型并返回 Relation 对象?
第二个问题,为什么 :include 为每个定义的模型创建 sql 查询而不是创建一个大的连接查询?

# match.rb
class Match < ActiveRecord::Base
  has_many :rounds
  has_many :participations
  has_many :players, :through => :participations
  has_many :scores
  has_many :clans, :through => :scores
  belongs_to :clan_1, :class_name => "Clan", :foreign_key => "clan_1_id"
  belongs_to :clan_2, :class_name => "Clan", :foreign_key => "clan_2_id"
  belongs_to :winner, :class_name => "Clan", :foreign_key => "winner_id"
  belongs_to :league
  belongs_to :tournament

# matches_controller.rb
@matches = Match.all(:include=>[:clans,:scores])

这是 Match.includes(:clans) 的日志输出:

Match Load (18.2ms)  SELECT "matches".* FROM "matches"
Score Load (4.5ms)  SELECT "scores".* FROM "scores" WHERE ("scores".match_id IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115))
Clan Load (0.5ms)  SELECT "clans".* FROM "clans" WHERE ("clans"."id" IN (1,7,9,2,5,3,4,8,10,6,11,12,13,14,15,16,17,18,19,20))

How to use eager loading while paginating with kaminari? I know that kaminari needs Relation object to work, how to retrieve models with :include and return Relation object?
And second question, why :include creates sql query for evry defined model instead of creating one big joined query?

# match.rb
class Match < ActiveRecord::Base
  has_many :rounds
  has_many :participations
  has_many :players, :through => :participations
  has_many :scores
  has_many :clans, :through => :scores
  belongs_to :clan_1, :class_name => "Clan", :foreign_key => "clan_1_id"
  belongs_to :clan_2, :class_name => "Clan", :foreign_key => "clan_2_id"
  belongs_to :winner, :class_name => "Clan", :foreign_key => "winner_id"
  belongs_to :league
  belongs_to :tournament

# matches_controller.rb
@matches = Match.all(:include=>[:clans,:scores])

This is what log outputs for Match.includes(:clans):

Match Load (18.2ms)  SELECT "matches".* FROM "matches"
Score Load (4.5ms)  SELECT "scores".* FROM "scores" WHERE ("scores".match_id IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115))
Clan Load (0.5ms)  SELECT "clans".* FROM "clans" WHERE ("clans"."id" IN (1,7,9,2,5,3,4,8,10,6,11,12,13,14,15,16,17,18,19,20))

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

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

发布评论

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

评论(2

冷情妓 2024-11-03 19:03:21

Rails 3.x 中有新的查询语法。所以试试这个

@matches = Match.includes(:clans,:scores)

In Rails 3.x there is new query syntax. So try this

@matches = Match.includes(:clans,:scores)
病毒体 2024-11-03 19:03:21

试试这个:

@matches = Match.includes([:clans,:scores]).all()
@matches_paginated = Kaminari.paginate_array(@matches).page(params[:page] || 1).per(20)

# And then
@matches_paginated.each do |m|
  m.clans.each do |c| # should not generate a new query
    c.name # should not generate a new query
  end
end

唯一的问题是这会急切加载所有其他页面(你真的不需要)

Try this:

@matches = Match.includes([:clans,:scores]).all()
@matches_paginated = Kaminari.paginate_array(@matches).page(params[:page] || 1).per(20)

# And then
@matches_paginated.each do |m|
  m.clans.each do |c| # should not generate a new query
    c.name # should not generate a new query
  end
end

The only problem with this is that this will eager load all the other pages (which you really don't need)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文