Ruby on rails Rails预加载与多个外键的关联

Ruby on rails Rails预加载与多个外键的关联,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,假设我有以下两个模型,分别由以下两个连接模型连接: class Game has_many :game_plays has_many :game_views end class Person has_many :game_plays has_many :game_views end # Games that a Person has played class GamePlay belongs_to :game belongs_to :person end # Gam

假设我有以下两个模型,分别由以下两个连接模型连接:

class Game
  has_many :game_plays
  has_many :game_views
end

class Person
  has_many :game_plays
  has_many :game_views
end

# Games that a Person has played
class GamePlay
  belongs_to :game
  belongs_to :person
end

# Games that a Person has viewed
class GameView
  belongs_to :game
  belongs_to :person
end
给定一个特定的游戏,我想获得同一个人游戏组合的游戏视图,例如:

game_play = GamePlay.first
game_view = GameView.find_by(game_id: game_play.game_id, person_id: game_play.person_id)
我还需要加载该关联

我很想在GamePlay和GameView之间建立一种关联,但到目前为止,我还没有尝试过什么

尝试1

这是可行的,但我不能包括:

尝试2

这显然是可行的,但我不能包含它,因为它没有定义为关联

有什么想法吗?谢谢

Rails 5.0.0postgres 9.6.2如何:

class GamePlay < ApplicationRecord
  belongs_to :game
  belongs_to :person
  has_one :game_view, through: :person, source: :game_views
end

irb(main):002:0> GamePlay.includes(:game_view).find(2)
  GamePlay Load (0.2ms)  SELECT  "game_plays".* FROM "game_plays" WHERE "game_plays"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  Person Load (0.2ms)  SELECT "people".* FROM "people" WHERE "people"."id" = 1
  GameView Load (0.2ms)  SELECT "game_views".* FROM "game_views" WHERE "game_views"."person_id" = 1
=> #<GamePlay id: 2, game_id: 1, person_id: 1>

irb(main):008:0> GamePlay.find(2).game_view
  GamePlay Load (0.1ms)  SELECT  "game_plays".* FROM "game_plays" WHERE "game_plays"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  GameView Load (0.2ms)  SELECT  "game_views".* FROM "game_views" INNER JOIN "people" ON "game_views"."person_id" = "people"."id" WHERE "people"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<GameView id: 2, game_id: 1, person_id: 1>

这不使用游戏id。在将游戏性和GameView重构为一个带有类列的多态PersonGame模型之前,它可能是值得的。我考虑合并这些表已经有一段时间了,正是出于这个原因。我希望有一种比重构更简单的方法,谢谢你的建议。
GamePlay.includes(:game_view).first
# => ArgumentError: The association scope 'game_view' is instance dependent (the scope block takes an argument). Preloading instance dependent scopes is not supported.
class GamePlay
  belongs_to :game
  belongs_to :person

  def game_view
    GameView.find_by(game_id: game_id, person_id: person_id)
  end
end
class GamePlay < ApplicationRecord
  belongs_to :game
  belongs_to :person
  has_one :game_view, through: :person, source: :game_views
end

irb(main):002:0> GamePlay.includes(:game_view).find(2)
  GamePlay Load (0.2ms)  SELECT  "game_plays".* FROM "game_plays" WHERE "game_plays"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  Person Load (0.2ms)  SELECT "people".* FROM "people" WHERE "people"."id" = 1
  GameView Load (0.2ms)  SELECT "game_views".* FROM "game_views" WHERE "game_views"."person_id" = 1
=> #<GamePlay id: 2, game_id: 1, person_id: 1>

irb(main):008:0> GamePlay.find(2).game_view
  GamePlay Load (0.1ms)  SELECT  "game_plays".* FROM "game_plays" WHERE "game_plays"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  GameView Load (0.2ms)  SELECT  "game_views".* FROM "game_views" INNER JOIN "people" ON "game_views"."person_id" = "people"."id" WHERE "people"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<GameView id: 2, game_id: 1, person_id: 1>