Rails ActiveRecord连接三个表并检索嵌套对象

时间:2016-01-02 19:56:17

标签: ruby-on-rails activerecord

我有三个模型类:游戏,团队和玩家:

class Game < ActiveRecord::Base
  has_many :teams
end

class Team < ActiveRecord::Base
  belongs_to :game
  has_many :players
end

class Player < ActiveRecord::Base
  belongs_to :team
end

class CreateGames < ActiveRecord::Migration
  def change
    create_table :games do |t|
      t.string :play_date
      t.string :date

      t.timestamps null: false
    end
  end
end

class CreateTeams < ActiveRecord::Migration
  def change
    create_table :teams do |t|
      t.integer :team_number
      t.references :game, index: true

      t.timestamps null: false
    end
    add_foreign_key :teams, :games
  end
end

class CreatePlayers < ActiveRecord::Migration
  def change
    create_table :players do |t|
      t.string :name
      t.references :team, index: true

      t.timestamps null: false
    end
    add_foreign_key :players, :teams
  end
end

我正在尝试编写一个Active Record查询来返回一个包含1个游戏,M个团队,N个玩家的嵌套对象的对象。因此,例如,我希望我返回的数据看起来像这样:

{ "id" => "1", "play_date"=>"2016-01-28", 
  "teams" =>
  [{"id" => "1", "game_id" => "1", "team_number" => "1", 
    "players" =>
    [{"id" => "1", "team_id" => "1", "name" => "Jim"},
     {"id" => "2", "team_id" => "1", "name" => "Bob"},
     {"id" => "3", "team_id" => "1", "name" => "Sally"}
    ]
   },
   {"id" => "2", "game_id" => "1", "team_number" => "2", 
    "players" =>
    [{"id" => "4", "team_id" => "2", "name" => "Ed"},
     {"id" => "5", "team_id" => "2", "name" => "Molly"},
     {"id" => "6", "team_id" => "2", "name" => "Tim"}
    ]
   }
  ]
}

我最接近工作的是:

@data = Player.select("players.*, teams.*").joins(team: :game).where(games: {id: params[:id]}) 

返回类似的内容:

[
#<Player id: 1, name: "Jim", team_id: 1, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">, 
#<Player id: 2, name: "Bob", team_id: 1, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">, 
#<Player id: 3, name: "Sally", team_id: 1, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">, 
#<Player id: 4, name: "Ed", team_id: 2, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">, 
#<Player id: 5, name: "Molly", team_id: 2, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">, 
#<Player id: 6, name: "Tim", team_id: 2, created_at: "2016-01-02 19:27:52", updated_at: "2016-01-02 19:27:52">
]

我尝试了上面代码的多种变体来尝试获取一组嵌套对象,就像在我期望的输出示例中一样,但我总是得到只返回单个对象级别的结果。

任何人都可以帮助返回包含嵌套对象的结果吗?感谢。

1 个答案:

答案 0 :(得分:0)

我想我需要休息一下,我现在能够解决这个问题。

我认为我的问题是依靠.inspect命令检查并查看是否正在加载多个级别的对象。如果我只是将查询简化为:

,则结果证明
<% @data.teams.each do |team| %>
  <%= team.players[0].name %>
<% end %>

然后实际尝试在我的视图中循环遍历数据:

ionic serve

这使我能够访问我需要的所有数据。我猜测由于延迟加载(但可能不是),检查并未显示所有数据。