【发布时间】: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