ruby-on-rails - software - ruby on rails website
Rieles 5: consulta ActiveRecord O (5)
¿Cómo se hace una consulta en
Rails 5
ActiveRecord?
Además, ¿es posible encadenar
or
con
where
en las consultas ActiveRecord?
(Solo una adición a la respuesta de KM Rakibul Islam).
Usando ámbitos, el código puede volverse más bonito (dependiendo de la mirada):
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
La capacidad de encadenar
or
cláusula junto con la cláusula
where
en la consulta
ActiveRecord
estará disponible en
Rails 5
.
Vea la
discusión relacionada y la solicitud de extracción
.
Por lo tanto, podrá hacer lo siguiente en Rails 5 :
Para obtener una
post
con
id
1 o 2:
Post.where(''id = 1'').or(Post.where(''id = 2''))
Algunos otros ejemplos:
(A y B) || DO:
Post.where(a).where(b).or(Post.where(c))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Necesitaba hacer un
(A && B) || (C && D) || (E && F)
(A && B) || (C && D) || (E && F)
Pero en el estado actual de Rails
5.1.4
, esto se vuelve demasiado complicado para lograrlo con la cadena o Arel.
Pero todavía quería usar Rails para generar la mayor cantidad de consultas posible.
Entonces 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 ''))
}
Lo que producirá el resultado de la consulta esperada:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
Y ahora puedo combinar esto fácilmente con otros ámbitos, etc. sin ningún OR incorrecto.
La belleza es que mi sql_where toma argumentos normales de la cláusula
sql_where(name: ''John'', role: ''admin'')
:
sql_where(name: ''John'', role: ''admin'')
generará
(name = ''John'' AND role = ''admin'')
.
Rails 5 tiene capacidad para
or
cláusula con
where
.
Por ejemplo.
User.where(name: "abc").or(User.where(name: "abcd"))