首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails/Arel -组合AREL谓词时的优先级

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

Stack Overflow用户
提问于 2011-06-29 16:12:29
回答 3查看 1.9K关注 0票数 5

一个模型有两个属性的兴趣,名字和城镇。我想找理查德(伦敦)和布莱恩(马德里)。

长时间的,

代码语言:javascript
复制
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就会给出一个意想不到的反应:

代码语言:javascript
复制
"(`person`.`forename` = 'Richard' AND `person`.`town` = 'London' OR `person`.`forename` = 'Brian' AND `person`.`town` = 'Madrid')"

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-06 14:21:57

这实际上是正确的查询,因为在大多数SQL方言中,运算符优先级高于OR。如果您要翻转它和两个OR谓词,它将在paren中包装OR谓词。

代码语言:javascript
复制
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)"
票数 2
EN

Stack Overflow用户

发布于 2013-05-13 09:39:44

对于Rails 3.2.13,请使用Arel::Nodes::Grouping。也见方法RubyDoc

代码语言:javascript
复制
pt = Person.arel_table
pred1 = person_table[:forename].eq("Richard").and(person_table[:town].eq("London"))
pred2 = person_table[:forename].eq("Rick").and(person_table[:town].eq("US"))
pt.grouping(pred1).or(pt.grouping(pred2)).to_sql

=> (("people"."forename" = 'Richard' AND "people"."town" = 'London') OR ("people"."forename" = 'Rick' AND "people"."town" = 'US'))
票数 1
EN

Stack Overflow用户

发布于 2011-07-01 07:39:12

尝试直接使用arel_table

代码语言:javascript
复制
person_table = Person.arel_table
pred1 = person_table[:forename].eq("Richard").and(person_table[:town].eq("London"))
pred2 = person_table[:forename].eq("Rick").and(person_table[:town].eq("US"))
pred1.or(pred2).to_sql

这产生了(“people”、“forename”=“Richard”和“people”、“town”= 'London')或(“people”、“forename”= 'Rick‘和“people”、“town”= 'US'))。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6523810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档