具有AND和OR的复杂Arel条件

时间:2014-09-24 14:40:52

标签: ruby-on-rails arel

我有一个问题,即关于操作优先级,在ANDOR中编写了几个条件。

因此,我需要生成以下SQL字符串以传递给where方法:

where("NOT ((assignments.to IS NOT NULL AND assignments.to < :start_date) OR assignments.from > :end_date)", start_date: date.at_beginning_of_week, end_date: date.at_end_of_week)

我用Arel重写了它:

table = Assignment.arel_table
where(
  table[:from].gt(date.at_end_of_week).
  or(
    table[:to].not_eq(nil).and(table[:to].lt(date.at_end_of_week))
  ).not
)

但是Arel并没有在AND条件下放置括号,因此这个条件会选择错误的数据。如何在这种情况下放置括号?

2 个答案:

答案 0 :(得分:5)

您可以使用table.grouping方法将表达式包装在括号中,因此整个事情可以像这样

table = Assignment.arel_table
where(
  table[:from].gt(date.at_end_of_week).
  or(
    table.grouping(table[:to].not_eq(nil).and(table[:to].lt(date.at_end_of_week)))
  ).not
)

答案 1 :(得分:-1)

你可以尝试:

table[:from].lt(end_date).and(
  table[:to].eq(nil).or(table[:to].gt(start_date))
)

也许我会错过一些东西,但无论如何你应该避免在sql中使用NOT或在ruby中使用unless因为这不是好习惯