¿Cómo se realiza una or
consulta en Rails 5 ActiveRecord? Además, ¿es posible encadenar or
con where
consultas ActiveRecord?
¿Cómo se realiza una or
consulta en Rails 5 ActiveRecord? Además, ¿es posible encadenar or
con where
consultas ActiveRecord?
Respuestas:
La capacidad de encadenar or
cláusula junto con where
cláusula en ActiveRecord
consulta estará disponible en Rails 5 . Consulte la discusión relacionada y la solicitud de extracción .
Por lo tanto, podrá hacer las siguientes cosas en Rails 5 :
Para obtener un post
con id
1 o 2:
Post.where('id = 1').or(Post.where('id = 2'))
Algunos otros ejemplos:
(A && B) || C:
Post.where(a).where(b).or(Post.where(c))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
esto debe crear (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Necesitaba hacer un (A && B) || (C && D) || (E && F)
Pero en el 5.1.4
estado actual de Rails , esto es demasiado complicado de lograr con la cadena o de Arel. Pero todavía quería usar Rails para generar la mayor cantidad posible de consultas.
Así que hice un pequeño truco:
En mi modelo creé un método privado llamado sql_where
:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
A continuación, en mi alcance, creé una matriz para contener los OR
scope :whatever, -> {
ors = []
ors << sql_where(A, B)
ors << sql_where(C, D)
ors << sql_where(E, F)
# Now just combine the stumps:
where(ors.join(' OR '))
}
Que producirá el resultado de la consulta se esperaba:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
Y ahora puedo combinar esto fácilmente con otros alcances, etc. sin ningún quirófano incorrecto.
La belleza es que mi sql_where toma argumentos normales de cláusula where:
sql_where(name: 'John', role: 'admin')
generará (name = 'John' AND role = 'admin')
.
.merge
como equivalente de && y construir un árbol adecuado para capturar sus parens. Algo como ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
, suponiendo que cada uno de los ámbitos se parezca aModel.where(...)
Rails 5 tiene capacidad para or
cláusula con where
. Por ejemplo.
User.where(name: "abc").or(User.where(name: "abcd"))