【发布时间】:2013-02-23 06:42:46
【问题描述】:
我正在尝试在我的 rails 模型中构建一个范围,当它被调用时,它将在 7 个布尔字段上为我提供一组嵌套的 AND 和 OR 子句。为了清楚起见,这里有一个简化的列名示例:
SELECT * FROM mytable
WHERE (a AND b AND c) OR (a AND d AND e) OR (a AND f AND g);
请注意,列 a 出现在所有三个子句中。另一种写法是:
SELECT * FROM mytable
WHERE a AND ((b AND c) OR (d AND e) OR (f AND g));
Arel 似乎对第二种形式不太宽容。我已经非常接近以下范围:
scope :needs_any_delivery, lambda {
table = self.arel_table
common_assert = table[:a].eq(true)
where(
common_assert.and(
table[:b].eq(true).and(
table[:c].eq(false)
)
).or(
common_assert.and(
table[:d].eq(true).and(
table[:e].eq(false)
)
).or(
common_assert.and(
table[:f].eq(true).and(
table[:g].eq(false)
)
)
)
)
)
}
这会产生以下查询:
SELECT * FROM mytable
WHERE (
(a = 't' AND b = 't' AND c = 'f'
OR (a = 't' AND d = 't' AND e = 'f' OR a = 't' AND f = 't' AND g = 'f')
)
)
已接近,但第三个AND 组并未与第二个AND 组分开。我发现如果我在第三组末尾添加一些额外的虚假 or 子句,那么 Arel 会适当地将第三个子句单独分组......但这似乎是一个 hack。
想知道是否有任何 Rails/arel 大师有任何想法。谢谢!
【问题讨论】:
标签: ruby-on-rails activerecord arel