【问题标题】:Chaining a scope with 'where' results in SQL being appended (not merged)?使用“where”链接范围会导致附加 SQL(未合并)?
【发布时间】:2013-03-13 15:29:54
【问题描述】:

我的模型如下所示:

class User < ActiveRecord::Base    
 has_many :created_games, class_name: 'Game', foreign_key: 'challenger_id'
 has_many :challenged_games, class_name: 'Game', foreign_key: 'opponent_id'  
end

class Game < ActiveRecord::Base
  belongs_to :challenger, :class_name => 'User'
  belongs_to :opponent, :class_name => 'User'
end

用户故事 作为用户,我想查看我可以挑战并与之一起玩游戏的用户列表。如果我们之间存在现有游戏,我无法向用户挑战新游戏。

作用域

我有一个类方法如下:

def self.challeangable_for(user_id)

    challengeable_users = User.joins("LEFT JOIN ( SELECT games.challenger_id, games.opponent_id FROM games where games.challenger_id = #{user_id} OR games.opponent_id = #{user_id}) as g on g.challenger_id = users.id or g.opponent_id = users.id WHERE g.challenger_id is null and g.opponent_id is null") 

end

这会正确生成“可挑战用户”列表,但我似乎无法链接此查询。例如,如果我执行User.challengeable_users(1).where(gender: 'm'),rails 会将 WHERE 子句附加到末尾,查询将失败:

SQLite3::SQLException: near "WHERE": syntax error: SELECT "users".* FROM "users" LEFT JOIN ( SELECT games.challenger_id, games.opponent_id FROM games where games.challenger_id = 1 OR games.opponent_id = 1) as g on g.challenger_id = users.id or g.opponent_id = users.id WHERE g.challenger_id is null and g.opponent_id is null WHERE "users"."gender" = 'm' ORDER BY users.created_at DESC

而且,它又长又丑。有没有更好的办法?我尝试使用“包含”,但没有找到一种方法来指定要加入的不同(非标准)外键?

我意识到我有点专注于生成 LEFT JOIN 查询的解决方案。另一种解决方案是生成 EXISTS IN 查询,但我不知道如何编写。

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.2


    【解决方案1】:

    是的,你可以重写一下:

    challengeable_users = User.joins("LEFT JOIN ( 
      SELECT games.challenger_id, games.opponent_id FROM games where games.challenger_id = #       {user_id} OR games.opponent_id = #{user_id}
      ) as g on g.challenger_id = users.id or g.opponent_id = users.id"
    ).where("g.challenger_id is null").where("g.opponent_id is null")
    

    然后你可以进一步应用你的性别条件。

    【讨论】:

    • 太棒了,这行得通!我花了很多时间在这上面,但最后它开始有点意思了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 2010-12-02
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多