Rails/Arel - 组合 AREL 谓词时的优先级

2024-04-06

模型有两个有趣的属性,forename and town。我想搜索理查德(伦敦)和布莱恩(马德里)。

从长远来看,

p=Person.scoped
pred1=p.table[:forename].eq('Richard').and(p.table[:town].eq('London'))
pred2=p.table[:forename].eq('Brian').and(p.table[:town].eq('Madrid'))
pred3=pred1.or(pred2)

我希望这会将谓词括在括号中以保持查询的完整性。但查看 pred3.to_sql 会得到意想不到的响应:

"(`person`.`forename` = 'Richard' AND `person`.`town` = 'London' OR `person`.`forename` = 'Brian' AND `person`.`town` = 'Madrid')"

如何让 Arel 生成正确的查询?


这其实is正确的查询,因为在大多数 SQL 方言中 AND 的运算符优先级高于 OR。如果你要翻转它和 AND 2 OR 谓词,它会将 OR 谓词包裹在括号中。

t = Arel::Table.new('blah')

a = (t[:a].eq(nil).and(t[:b].eq(nil)))
b = (t[:a].not_eq(nil).and(t[:b].not_eq(nil)))
a.or(b).to_sql

  => "(`blah`.`a` IS NULL AND `blah`.`b` IS NULL OR `blah`.`a` IS NOT NULL AND `blah`.`b` IS NOT NULL)"

a = (t[:a].eq(nil).or(t[:b].eq(nil)))
b = (t[:a].not_eq(nil).or(t[:b].not_eq(nil)))
a.and(b).to_sql

  => "(`blah`.`a` IS NULL OR `blah`.`b` IS NULL) AND (`blah`.`a` IS NOT NULL OR `blah`.`b` IS NOT NULL)"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails/Arel - 组合 AREL 谓词时的优先级 的相关文章

随机推荐