【问题标题】:Returning array of objects via named_scope -- has_many...belongs_to association; UNION ALL query通过 named_scope 返回对象数组 -- has_many...belongs_to 关联; UNION ALL 查询
【发布时间】:2011-06-22 09:16:12
【问题描述】:

我正在寻找一个答案,该答案将通过(最好)named_scope 或通过 User 模型上执行某些操作的类方法返回一组用户对象。

那就不用多说了……

我有两个表:用户和战斗。

  • 用户进行了多次战斗(has_many :fights, :foreign_key => 'challenge_id or challengee_id')
  • 战斗属于用户(belongs_to :challenger, :class_name => 'User'...belongs_to :challengee, :class_name => 'User')

Fight 关注以下几列:

  • challenge_id (user_id fk)
  • challenge_id (user_id fk)
  • challenge_won(布尔值)

如您所见,用户可以是挑战者或挑战者,但不能同时是两者。

  • 如果用户是挑战者并且challenger_won = true,则视为获胜。
  • 如果用户是挑战者并且challenge_won = false,则视为获胜。
  • 如果challenge_won = null,则忽略它。

我有一个原始 SQL 语句,它返回一个按大多数 wins 属性分组的 fighter 属性(user_id):

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;

因此,鉴于此信息,我如何通过(最好)named_scope 或通过 User 模型上执行某些操作的类方法返回用户对象数组?

【问题讨论】:

  • 考虑将fights 表中的challenger_won 列更改为winner_id (user_id fk),这将使查找结果更加清晰。然后你可以有一个has_many :wins, :class_name => 'Fight', :foreign_key => 'winner_id' 这将允许你做user.wins.count 来找到总胜利

标签: sql mysql ruby-on-rails named-scope


【解决方案1】:

我认为您可以尝试这样的方法来重新创建查询结果:

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

但是,对于缓存目的,您可能需要考虑将 win_count 字段添加到 User 模型。如果你为战斗的获胜者创建了一个 setter 方法,你可以在 win_count 改变的那一刻增加它。

【讨论】:

  • 啊,没错!不敢相信我没想过只是在用户模型中添加计数器……这绝对是最好的方法……谢谢
【解决方案2】:

或者,没有连接(特定于 mysql)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多