2011-04-01 74 views
5

我正在使用Rails應用程序進行錦標賽。我有三個型號即時通訊與此查詢工作:Rails 3在一個查詢中包含多個表格

class Player < ActiveRecord::Base 
    validates :name, :uniqueness => true 
    has_and_belongs_to_many :tournaments 

class Tournament < ActiveRecord::Base 
    belongs_to :tournament_type 
    has_and_belongs_to_many :players 
    has_many :player_matches, :dependent => :destroy 

class PlayerMatch < ActiveRecord::Base 
    belongs_to :player_one, :class_name => "Player", :foreign_key => "player_one" 
    belongs_to :player_two, :class_name => "Player", :foreign_key => "player_two" 

在tournaments_controller的表演動作,即時致電以下查詢:

Tournament.where(:id => params[:id]).includes(:player_matches, :players).first() 

雖然比賽和player_matches在一個單一的完成加盟,玩家單獨查詢,因爲我的代碼依賴於他們:

Player Load (0.4ms) SELECT `players`.*, t0.tournament_id as the_parent_record_id FROM `players` INNER JOIN `players_tournaments` t0 ON `players`.id = t0.player_id WHERE (t0.tournament_id = 14) 
Player Load (0.2ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 5 LIMIT 1 
Player Load (0.2ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 9 LIMIT 1 
Player Load (0.2ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 1 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 8 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 3 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 2 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 7 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 6 LIMIT 1 
Player Load (0.1ms) SELECT `players`.* FROM `players` WHERE `players`.`id` = 4 LIMIT 1 

我怎樣才能改變這件事,所以它是所有在一個查詢拉?

+0

拋棄它作爲評論類似的東西解決了我的N + 1問題,但我不確定它是否適用於您。如果您將'includes'調用改爲'includes(:player_matches =>:players)',你會得到什麼? – 2011-04-01 22:20:50

+0

另外,拋出這個......確保你正在查看生產模式中使用的SQL,而不是開發。 – 2011-04-01 22:37:00

+0

尚未在生產模式下運行。該輸出來自終端中的服務器控制檯,應該是日誌,所以我知道我有正確的輸出:)。 – agmcleod 2011-04-01 23:05:44

回答

10
Tournament.where(:id => params[:id]).includes([{:player_matches => :player_one}, :players]).first() 

這應該做的伎倆。實際上,數組符號和散列符號的組合起初有點麻煩,但是與控制檯一起工作,你會發現哪種語法不會崩潰:)

+0

感謝您的回覆。我仍然收到多個玩家查詢回來雖然:(我不知道如果也許我的問題在於我如何使用數據,或者我有如何結構化數據庫。 – agmcleod 2011-04-15 11:16:43