Rails 5: ActiveRecord O consulta
¿Cómo hacer una consulta or
en Rails 5 ActiveRecord? Además, ¿es posible encadenar or
con where
en consultas ActiveRecord?
4 answers
La capacidad de encadenar la cláusula or
junto con la cláusula where
en la consulta ActiveRecord
estará disponible en Rieles 5. Véase la discusión relacionada con y la pull request.
Por Lo tanto, usted será capaz de hacer las siguientes cosas en Rieles 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-20 12:41:25
No necesitamos esperar a que rails 5 utilice esta consulta OR
. También podemos usarlo con rails 4.2.3
. Hay un backport aquí.
Gracias a Eric-Guopara gema donde-o, Ahora podemos agregar esta funcionalidad OR
en >= rails 4.2.3
también usando esta gema.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-24 06:11:27
Necesitaba hacer un (A && B) || (C && D) || (E && F)
Pero en el estado actual de Rails 5.1.4
esto es demasiado complicado de lograr con Arel o-chain.
Pero todavía quería usar Rails para generar tanto de la consulta como fuera posible.
Así que hice un pequeño hack:
En mi modelo creé un método private 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 ámbito, creé un array 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á la consulta esperada resultado:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
Y ahora puedo combinar fácilmente esto con otros ámbitos, etc. sin ningún quirófano ilícito.
La belleza es que mi sql_where toma argumentos normales de la cláusula where:
sql_where(name: 'John', role: 'admin')
generará (name = 'John' AND role = 'admin')
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 13:21:27
(Solo una adición a la respuesta de Km Rakibul Islam.)
Usando scopes, el código puede volverse más bonito (dependiendo de la mirada de los ojos):
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 19:51:15