Dmy*_*iak 58 ruby sql activerecord ruby-on-rails arel
如何使用逻辑OR而不是AND组合2个不同的条件?
注意:作为轨道范围生成2个条件,并且不能轻易地将其更改为where("x or y")直接类似的条件.
简单的例子:
admins = User.where(:kind => :admin)
authors = User.where(:kind => :author)
Run Code Online (Sandbox Code Playgroud)
它很容易应用和条件(对于这个特殊情况是没有意义的):
(admins.merge authors).to_sql
#=> select ... from ... where kind = 'admin' AND kind = 'author'
Run Code Online (Sandbox Code Playgroud)
但是,如何生成具有2种不同Arel关系的以下查询?
#=> select ... from ... where kind = 'admin' OR kind = 'author'
Run Code Online (Sandbox Code Playgroud)
似乎(根据Arel自述文件):
OR运算符尚不支持
但是我希望它不适用于此并期望写出如下内容:
(admins.or authors).to_sql
Run Code Online (Sandbox Code Playgroud)
Ale*_*fee 93
ActiveRecord查询是ActiveRecord::Relation对象(令人生气地不支持or),而不是Arel对象(它们).
[ 更新:从Rails 5开始,支持"或" ActiveRecord::Relation; 见/sf/answers/2327380961/ ]
但幸运的是,他们的where方法接受ARel查询对象.所以,如果User < ActiveRecord::Base......
users = User.arel_table
query = User.where(users[:kind].eq('admin').or(users[:kind].eq('author')))
Run Code Online (Sandbox Code Playgroud)
query.to_sql 现在显示令人放心:
SELECT "users".* FROM "users" WHERE (("users"."kind" = 'admin' OR "users"."kind" = 'author'))
Run Code Online (Sandbox Code Playgroud)
为清楚起见,您可以提取一些临时的部分查询变量:
users = User.arel_table
admin = users[:kind].eq('admin')
author = users[:kind].eq('author')
query = User.where(admin.or(author))
Run Code Online (Sandbox Code Playgroud)
当然,一旦有了查询,就可以query.all用来执行实际的数据库调用.
jsw*_*ner 70
我参加聚会有点晚了,但这是我能提出的最佳建议:
admins = User.where(:kind => :admin)
authors = User.where(:kind => :author)
admins = admins.where_values.reduce(:and)
authors = authors.where_values.reduce(:and)
User.where(admins.or(authors)).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE ((\"users\".\"kind\" = 'admin' OR \"users\".\"kind\" = 'author'))"
Run Code Online (Sandbox Code Playgroud)
OR运算符的工作方式如下:
Run Code Online (Sandbox Code Playgroud)users.where(users[:name].eq('bob').or(users[:age].lt(25)))
从我们的Rails 5开始ActiveRecord::Relation#or,允许你这样做:
User.where(kind: :author).or(User.where(kind: :admin))
Run Code Online (Sandbox Code Playgroud)
...它被翻译成你期望的sql:
>> puts User.where(kind: :author).or(User.where(kind: :admin)).to_sql
SELECT "users".* FROM "users" WHERE ("users"."kind" = 'author' OR "users"."kind" = 'admin')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33539 次 |
| 最近记录: |