2011-04-01 18 views
5

Im trabajando en una aplicación de rieles para torneos. He tres modelos estoy trabajando con el siguiente consulta:Rails 3 Incluyendo varias tablas en una consulta

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" 

En la acción show del tournaments_controller, im llamando a la siguiente consulta:

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

Si bien los torneos y player_matches se realizan en una sola unirse los jugadores se consultan de forma individual, ya que mi código depende de ellos:

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 

cómo puedo cambiar esto, por lo que todo está tirado en una consulta?

+0

Lanzando esto como un comentario desde algo similar solucionó mi problema de N + 1, pero no estoy seguro si funcionará para ti. ¿Qué obtienes si cambias tu llamada 'includes' a' includes (: player_matches =>: players) '? –

+0

Además, lanzando esto ... asegúrese de que está buscando el SQL utilizado en modo de producción, no en desarrollo. –

+0

Todavía tienen que ejecutar esto en modo de producción. Esa salida es desde la consola del servidor en la terminal, como se supone para los registros, entonces sé que tengo la salida correcta :). – agmcleod

Respuesta

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

Eso debería hacer el truco. Y realmente, la combinación de notación de matriz y hash es un poco desordenada para ser ordenada al principio, pero trabaja con la consola y descubrirás qué sintaxis no se cuelga :)

+0

Gracias por la respuesta. Todavía estoy recibiendo varias consultas de jugadores :(. Me pregunto si tal vez mi problema radique en cómo estoy usando los datos, o cómo tengo estructurada la base de datos. – agmcleod

Cuestiones relacionadas