2011-02-06 6 views
5

Estoy buscando una respuesta que devuelva una matriz de objetos de usuario a través de (preferiblemente) un named_scope o mediante un método de clase en el modelo de usuario que realiza alguna manipulación.Devolución de una matriz de objetos mediante named_scope - has_many ... belongs_to association; UNION TODA consulta

Así que sin más preámbulos ...

Tengo dos tablas: los usuarios y peleas.

  • usuario tiene muchas peleas (has_many: peleas,: 'challenger_id o challengee_id' foreign_key =>)
  • lucha pertenece a un usuario (belongs_to: retador,: class_name => 'Usuario' ... belongs_to: challengee ,: class_name => 'usuario')

lucha tiene las siguientes columnas de preocupación:

  • challenger_id (user_id FK)
  • chall engee_id (user_id FK)
  • challenger_won (booleano)

Como se puede ver, un usuario puede ser un desafío o una challengee, pero no ambos.

  • Si el usuario es un retador y challenger_won = true, entonces se considera una victoria.
  • Si el usuario es un challengee y challenger_won = false, entonces se considera una ganancia.
  • Si el challenger_won = null, simplemente ignórelo.

tengo una instrucción SQL prima que devuelve un atributo de combate (user_id) agrupados por más victorias atribuyen:

SELECT a.fighter, COUNT(*) AS wins 
    FROM (SELECT challenger_id AS fighter 
      FROM fights 
     WHERE challenger_won = TRUE 
     UNION ALL 
     SELECT challengee_id AS fighter 
      FROM fights 
     WHERE challenger_won = FALSE 
     ) AS a 
GROUP BY a.fighter; 

Así que dada esta información, ¿cómo puedo devolver una matriz de objetos de usuario a través de (preferiblemente) un named_scope o mediante un método de clase en el modelo de usuario que realiza alguna manipulación?

+0

Considere cambiar la columna '' challenger_won' en su mesa fights', a un 'winner_id' (user_id FK) que hará hallazgo gana mucho más limpio . Podrías tener un 'has_many: wins,: class_name => 'Fight',: foreign_key => 'winner_id'' que te permitirá hacer' user.wins.count' para encontrar el total de victorias – joshnuss

Respuesta

4

Creo que se puede intentar algo como esto para recrear el resultado de su búsqueda:

class User 
    named_scope :winners, 
     :select => 'users.*, COUNT(fight.id) AS wins', 
     :join => :fights, 
     :conditions => ['(fights.challenger_id = user_id AND fights.challenger_won = TRUE) OR (fights.challengee_id = user_id AND NOT fights.challenger_won = FALSE)'] 
     :group => 'user_id' 
end 

Sin embargo, para puposes de almacenamiento en caché, es posible que desee considerar la adición de un campo win_count al modelo de usuario. Si creas un método setter para el ganador de una pelea, puedes incrementar la cuenta win_ justo en ese momento cuando cambie.

+0

ahh, ¡está bien! No puedo creer que no haya pensado en agregar un contador al modelo de usuario ... definitivamente es el mejor enfoque ... gracias – keruilin

0

O, sin la unión (MySQL específica)

class User 
    named_scope :winners, 
    :select => 'if(challenger_won = FALSE,challenger,challengee) as winner,COUNT(id) AS wins ', 
    :group => 'user_id' 
end 
Cuestiones relacionadas