Como você faz uma or
consulta no Rails 5 ActiveRecord? Além disso, é possível a cadeia or
com where
no ActiveRecord consultas?
ruby-on-rails
ruby
activerecord
ruby-on-rails-5
rails-activerecord
KM Rakibul Islam
fonte
fonte
Respostas:
A capacidade de encadear
or
cláusula junto com awhere
cláusula naActiveRecord
consulta estará disponível no Rails 5 . Veja a discussão relacionada e a solicitação de pull .Então, você será capaz de fazer as seguintes coisas no Rails 5 :
Para obter um
post
comid
1 ou 2:Alguns outros exemplos:
(A && B) || C:
(A || B) && C:
fonte
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
isso deve criar (a || b) && (c || d)ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Não precisamos esperar pelo Rails 5 para usar esta
OR
consulta. Também podemos usá-lo comrails 4.2.3
. Há um backport aqui .Agradeço a Eric-Guo por gem where-or , Agora podemos adicionar essa
OR
funcionalidade ao>= rails 4.2.3
usar esta gem.fonte
(Apenas um acréscimo à resposta de KM Rakibul Islam.)
Usando escopos, o código pode se tornar mais bonito (dependendo da aparência dos olhos):
fonte
Eu precisava fazer um
(A && B) || (C && D) || (E && F)
Mas no
5.1.4
estado atual de Rails , isso é muito complicado de se realizar com o Arel ou cadeia. Mas eu ainda queria usar o Rails para gerar o máximo de consulta possível.Então, fiz um pequeno hack:
No meu modelo, criei um método privado chamado
sql_where
:Em seguida, no meu escopo, criei uma matriz para conter os OR
Que irá produzir o resultado da consulta esperado:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.E agora posso facilmente combinar isso com outros osciloscópios, etc., sem nenhum OR incorreto.
A beleza é que meu sql_where aceita argumentos normais da cláusula where:
sql_where(name: 'John', role: 'admin')
will generate(name = 'John' AND role = 'admin')
.fonte
.merge
como o equivalente a && e construir uma árvore adequada para capturar seus parênteses. Algo como ...(scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
, supondo que cada um dos escopos se pareça comModel.where(...)
Rails 5 tem capacidade para
or
cláusula comwhere
. Por exemplo.fonte