我正在尝试在我的 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 大师有任何想法。谢谢!