我不明白什么时候渴望加载就足够了,什么时候不足够。我将举一个实际的例子:使用下图所示的模型,我必须获得参加过特定比赛的球队(因此我需要加入):
在我的MatchesController中,执行以下操作:
@matches = Match.scheduled_or_playing
.joins(match_locations: {scores: {team_match: :team}})
.includes(match_locations: {scores: {team_match: :team}})
在索引视图中,我执行以下操作:
<% @matches.each do |m| %>
<%= m.teams.map(&:name).join " | " %>
<% end
如下面的日志所示,这会触发很多查询:
SQL (5.1ms) SELECT "matches"."id" AS t0_r0, "matches"."server_id" AS t0_r1, "matches"."pool_id" AS t0_r2, "matches"."state" AS t0_r3, "matches"."can_draw" AS t0_r4, "matches"."scheduled_at" AS t0_r5, "matches"."created_at" AS t0_r6, "matches"."updated_at" AS t0_r7, "match_locations"."id" AS t1_r0, "match_locations"."match_id" AS t1_r1, "match_locations"."location_id" AS t1_r2, "match_locations"."created_at" AS t1_r3, "match_locations"."updated_at" AS t1_r4, "scores"."id" AS t2_r0, "scores"."match_location_id" AS t2_r1, "scores"."team_match_id" AS t2_r2, "scores"."points" AS t2_r3, "scores"."created_at" AS t2_r4, "scores"."updated_at" AS t2_r5, "team_matches"."id" AS t3_r0, "team_matches"."team_id" AS t3_r1, "team_matches"."created_at" AS t3_r2, "team_matches"."updated_at" AS t3_r3, "teams"."id" AS t4_r0, "teams"."encrypted_password" AS t4_r1, "teams"."remember_created_at" AS t4_r2, "teams"."sign_in_count" AS t4_r3, "teams"."current_sign_in_at" AS t4_r4, "teams"."last_sign_in_at" AS t4_r5, "teams"."current_sign_in_ip" AS t4_r6, "teams"."last_sign_in_ip" AS t4_r7, "teams"."ts_address" AS t4_r8, "teams"."ts_password" AS t4_r9, "teams"."picture_url" AS t4_r10, "teams"."name" AS t4_r11, "teams"."username" AS t4_r12, "teams"."created_at" AS t4_r13, "teams"."updated_at" AS t4_r14 FROM "matches" INNER JOIN "match_locations" ON "match_locations"."match_id" = "matches"."id" INNER JOIN "scores" ON "scores"."match_location_id" = "match_locations"."id" INNER JOIN "team_matches" ON "team_matches"."id" = "scores"."team_match_id" INNER JOIN "teams" ON "teams"."id" = "team_matches"."team_id" WHERE "matches"."state" IN (1, 2) ORDER BY matches.scheduled_at ASC
Team Load (1.1ms) SELECT "teams".* FROM "teams" INNER JOIN "team_matches" ON "teams"."id" = "team_matches"."team_id" INNER JOIN "scores" ON "team_matches"."id" = "scores"."team_match_id" INNER JOIN "match_locations" ON "scores"."match_location_id" = "match_locations"."id" WHERE "match_locations"."match_id" = $1 [["match_id", 56]]
Team Load (1.1ms) SELECT "teams".* FROM "teams" INNER JOIN "team_matches" ON "teams"."id" = "team_matches"."team_id" INNER JOIN "scores" ON "team_matches"."id" = "scores"."team_match_id" INNER JOIN "match_locations" ON "scores"."match_location_id" = "match_locations"."id" WHERE "match_locations"."match_id" = $1 [["match_id", 68]]
....(n times)
Team Load (1.5ms) SELECT "teams".* FROM "teams" INNER JOIN "team_matches" ON "teams"."id" = "team_matches"."team_id" INNER JOIN "scores" ON "team_matches"."id" = "scores"."team_match_id" INNER JOIN "match_locations" ON "scores"."match_location_id" = "match_locations"."id" WHERE "match_locations"."match_id" = $1 [["match_id", 47]]
但是,如果我以这种方式修改视图...
<% @matches.each do |m| %>
<%= m.teams %>
<% end %>
视图不会产生相同的结果,但是应该加载相同的类和属性。但是,神奇的是,现在急于加载,下面是日志
SQL (4.9ms) SELECT "matches"."id" AS t0_r0, "matches"."server_id" AS t0_r1, "matches"."pool_id" AS t0_r2, "matches"."state" AS t0_r3, "matches"."can_draw" AS t0_r4, "matches"."scheduled_at" AS t0_r5, "matches"."created_at" AS t0_r6, "matches"."updated_at" AS t0_r7, "match_locations"."id" AS t1_r0, "match_locations"."match_id" AS t1_r1, "match_locations"."location_id" AS t1_r2, "match_locations"."created_at" AS t1_r3, "match_locations"."updated_at" AS t1_r4, "scores"."id" AS t2_r0, "scores"."match_location_id" AS t2_r1, "scores"."team_match_id" AS t2_r2, "scores"."points" AS t2_r3, "scores"."created_at" AS t2_r4, "scores"."updated_at" AS t2_r5, "team_matches"."id" AS t3_r0, "team_matches"."team_id" AS t3_r1, "team_matches"."created_at" AS t3_r2, "team_matches"."updated_at" AS t3_r3, "teams"."id" AS t4_r0, "teams"."encrypted_password" AS t4_r1, "teams"."remember_created_at" AS t4_r2, "teams"."sign_in_count" AS t4_r3, "teams"."current_sign_in_at" AS t4_r4, "teams"."last_sign_in_at" AS t4_r5, "teams"."current_sign_in_ip" AS t4_r6, "teams"."last_sign_in_ip" AS t4_r7, "teams"."ts_address" AS t4_r8, "teams"."ts_password" AS t4_r9, "teams"."picture_url" AS t4_r10, "teams"."name" AS t4_r11, "teams"."username" AS t4_r12, "teams"."created_at" AS t4_r13, "teams"."updated_at" AS t4_r14 FROM "matches" INNER JOIN "match_locations" ON "match_locations"."match_id" = "matches"."id" INNER JOIN "scores" ON "scores"."match_location_id" = "match_locations"."id" INNER JOIN "team_matches" ON "team_matches"."id" = "scores"."team_match_id" INNER JOIN "teams" ON "teams"."id" = "team_matches"."team_id" WHERE "matches"."state" IN (1, 2) ORDER BY matches.scheduled_at ASC
我真的不明白为什么
编辑:
根据要求,我在这里添加模型:
团队
class Team < ActiveRecord::Base
has_many :team_matches
has_many :matches, :through => :team_matches
end
团队比赛
class TeamMatch < ActiveRecord::Base
belongs_to :team
has_many :scores, :dependent => :destroy, :inverse_of => :team_match
has_many :match_locations, through: :scores
end
分数
class Score < ActiveRecord::Base
belongs_to :team_match
belongs_to :match_location
end
比赛地点
class MatchLocation < ActiveRecord::Base
belongs_to :location
belongs_to :match
has_many :scores
accepts_nested_attributes_for :scores
has_many :team_matches, through: :scores
end
比赛
class Match < ActiveRecord::Base
has_many :match_locations
accepts_nested_attributes_for :match_locations, allow_destroy: true
has_many :scores, through: :match_locations
has_many :team_matches, through: :scores
has_many :teams, through: :team_matches
end
我认为ActiveRecord无法识别您希望teams
通过关联嵌套嵌套加载的方式。尝试仅包含teams
“匹配级别”而不是嵌套。
@matches = Match.scheduled_or_playing
.joins(:teams)
.includes(:teams)
如果您需要所有其他嵌套的紧急加载,则只需将其包含在以下内容中:
@matches = Match.scheduled_or_playing
.joins([:teams, {match_locations: {scores: {team_match: :team}}}])
.includes([:teams, {match_locations: {scores: {team_match: :team}}}])
检查您的日志,以确保查询和紧急加载按预期方式工作(包括性能)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句