2012-08-28 12 views
5

Tengo cuatro tablas:rieles activerecord tabla incluye múltiples

argumento con campos

  • id

comentarios con

  • Identificación
  • comment_id
  • argument_id
  • user_id

usuarios

  • id

apodos con

  • Identificación
  • proposal_id
  • user_id
  • nombre

cada argumento tiene muchos comentarios,

cada comentario pertenece a un usuario,

cada usuario tiene una específica apodo en el argumento.

Cuando obtengo los comentarios del argumento de DB, me gustaría incluir también los apodos de cada autor.

La respuesta es sobre la consulta ActiveRecord No sé cómo escribir.

he intentado con

@argument.comments.includes(:user => :nicknames) 

pero no parece funcionar y cuando llegue el apodo través apodo = @ argument.nicknames.find_by_user_id (comment.user.id) se ejecuta la consulta ...

[1m[36mNickname Load (0.6ms)[0m [1mSELECT "nicknames".* FROM "nicknames" WHERE "nicknames"."argument_id" = 59 AND "nicknames"."user_id" = 9 LIMIT 1[0m 

¿Alguna sugerencia?

Respuesta

0

Tal vez algo como:

@argument.includes(:comments => [{ :user => :nicknames }]) 

no lo probamos, aunque ...

2

Usted puede saber si una asociación se carga con loaded?.

Lo que está sucediendo aquí, si entiendo su problema, es que está tratando de ejecutar un buscador en una Relación ActiveRecord ::. Navegando rápidamente por the code, no parece que intente ver si una colección está cargada antes de emitir la consulta. Sin embargo, toma un bloque que evitará múltiples consultas. Por ejemplo (los nombres de los modelos se han cambiado porque estoy utilizando un proyecto de ejemplo que he creado para otra pregunta):

c = Canteen.first 
Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1 
=> #<Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11"> 

c.meals.loaded? 
=> false 

c.meals.find {|m| m.id == 3} 
    Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 
=> #<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb6784fa78,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41"> 

Ves en el último ejemplo que ActiveRecord emite la consulta para cargar los registros asociados. Esto se debe a que ActiveRecord llama al to_a en la asociación, lo que obliga a que se cargue todo el conjunto y luego se filtra según las condiciones del bloque. Obviamente, esto no es ideal.

Intentemos de nuevo, ansiosos por cargar la asociación.

c = Canteen.includes(:meals).first 
    Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1 
    Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" IN (1) 
=> #<Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11"> 

c.meals.loaded? 
=> true 

c.meals.find {|m| m.id == 3} 
=> #<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb68b596f0,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41"> 

En el último ejemplo aquí, verá que la colección no se carga de nuevo. En cambio, el bloque se usa para filtrar los registros ya cargados.

Como se puede ver a continuación, incluso si se cargan los registros, ActiveRecord emitirá una consulta para agarrar el registro asociado:

c.meals.loaded? 
=> true 

c.meals.find(1) 
    Meal Load (0.1ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = ? LIMIT 1 [["id", 1]] 
=> #<Meal id: 1, canteen_id: 1, name: "Enchiladas", price: #<BigDecimal:7fcb6584ce88,'0.699E1',18(45)>, created_at: "2012-12-13 00:04:40", updated_at: "2012-12-13 00:04:40"> 

SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = 3 
=> [#<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb68b808e0,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41">] 
0

Usted puede intentar algo como esto para incluir más de una tabla

User.find(:all, :include => Room.find(:all,:include => :review)) 
+2

no es encontrar (: todo) obsoleto? – coorasse

Cuestiones relacionadas