Ruby on rails 将作用域链接到';其中';是否导致SQL被追加(未合并)?

Ruby on rails 将作用域链接到';其中';是否导致SQL被追加(未合并)?,ruby-on-rails,activerecord,ruby-on-rails-3.2,Ruby On Rails,Activerecord,Ruby On Rails 3.2,我的模型是这样的: 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 belong

我的模型是这样的:

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
这将正确生成“可挑战用户”列表,但我似乎无法链接此查询。例如,如果我使用
User.challengeable\u users(1).where(性别:'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
而且,它又长又丑。有更好的办法吗?我尝试使用“includes”,但我没有找到一种方法指定一个不同的(非标准)外键加入


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

是的,您可以稍微重写一下:

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")

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

太棒了,这很有效!我花了这么多时间在这上面,但最后它开始有点意义了。谢谢!
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")