Rails 4或使用组查询连接表

时间:2015-01-21 17:02:25

标签: sql ruby-on-rails ruby-on-rails-4 join

我有一个像这样的Rails 4查询:

user.positions.where('positions.active = ? OR positions.deadline < ?', false, Date.current).joins(:cvs).where(cvs: {accepted: true}).group(:id).having('COUNT(cvs.id) = 3')

现在生成以下SQL查询:

SELECT `positions`.* FROM `positions` INNER JOIN `cvs` ON `cvs`.`position_id` = `positions`.`id` WHERE `positions`.`user_id` = 4 AND (positions.active = 0 OR positions.deadline < '2015-01-21') AND `cvs`.`accepted` = 1 GROUP BY id HAVING COUNT(cvs.id) = 3

我真正需要的是使第二个查询OR条件,但上面的查询会导致AND条件。

我也尝试了以下内容:

user.positions.joins(:cvs).where('positions.active = ? OR positions.deadline < ? OR cvs.accepted = 1 GROUP BY id HAVING COUNT(cvs.id) = ?', false, Date.current, 3)

但这是由Rails转换为

SELECT  `positions`.* FROM `positions` INNER JOIN `cvs` ON `cvs`.`position_id` = `positions`.`id` WHERE `positions`.`user_id` = 4 AND (positions.active = 0 OR positions.deadline < '2015-01-21' OR cvs.accepted = 1 GROUP BY id HAVING COUNT(cvs.id) = 3)

由于末尾的右括号而引发sql语法错误。没有左右括号或在2015-01-21&#39; 2015-01-21&#39;之后放置右括号它会奏效。但我不知道怎么告诉Rails不要在那里放任何括号。

(我实际想要查询的是所有未激活的职位或截止日期已达到的职位或职位有3个已接受的简历

1 个答案:

答案 0 :(得分:0)

ActiveRecord不能or,但Arel可以。惊人的scuttle.io将解决您的问题:

Position.select(Position.arel_table[Arel.star]).where(
  Position.arel_table[:user_id].eq(4).or(
    Position.arel_table[:active].eq(0).or(Position.arel_table[:deadline].lt('2015-01-21')).or(Cv.arel_table[:accepted].eq(1))
  )
).joins(
  Position.arel_table.join(Cv.arel_table).on(
    Cv.arel_table[:position_id].eq(Position.arel_table[:id])
  ).join_sources
).group(:id)