Supongamos que tengo los siguientes dos objetos:
first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation
¿Es posible combinar las dos relaciones para producir un ActiveRecord::Relation
objeto que contenga ambas condiciones?
Nota: Soy consciente de que puedo encadenar las rutas para obtener este comportamiento, lo que realmente me interesa es el caso en el que tengo dos ActiveRecord::Relation
objetos separados .
ruby-on-rails
rails-activerecord
arel
Patrick Klingemann
fuente
fuente
Respuestas:
Si desea combinar usando
AND
(intersección), usemerge
:Si desea combinar usando
OR
(union), use † :or
† Solo en ActiveRecord 5+; para 4.2 instale where-or backport.
fuente
ActiveRecord::Relation
tipo?merge
es una intersección, no una unión.#or
método se agregó a ActiveRecord :: Relation en enero de 2015, y formará parte de Rails 5.0 , que se enviará a fines de 2015. Permite el uso del operador OR para combinar cláusulas WHERE o HAVING. Puede pagar HEAD si lo necesita antes del lanzamiento oficial. Ver solicitud de combinación de extracción # 16052 @Arcolye @AndrewMarshall @ Aldo-xoen-GiambellucaLos objetos de relación se pueden convertir en matrices. Esto niega poder usar cualquier método ActiveRecord en ellos después, pero no necesité hacerlo. Hice esto:
Ruby 1.9, rieles 3.2
fuente
merge
en realidad no funciona asíOR
. Es simplemente intersección (AND
)Luché con este problema para combinar los objetos ActiveRecord :: Relation en uno y no encontré ninguna solución que funcionara para mí.
En lugar de buscar el método correcto para crear una unión a partir de estos dos conjuntos, me concentré en el álgebra de conjuntos. Puedes hacerlo de manera diferente usando la ley de De Morgan
ActiveRecord proporciona el método de fusión (AND) y también puede usar el método not o none_of (NOT).
Tienes aquí (A u B) '= A' ^ B '
ACTUALIZACIÓN: La solución anterior es buena para casos más complejos. En su caso, algo así será suficiente:
fuente
He podido lograr esto, incluso en muchas situaciones extrañas, utilizando el Arel incorporado de Rails .
Esto combina ambas relaciones ActiveRecord utilizando Arel's o .
Combinar, como se sugirió aquí, no funcionó para mí. Se eliminó el segundo conjunto de objetos de relación de los resultados.
fuente
Hay una gema llamada active_record_union que podría ser lo que estás buscando.
Su ejemplo de uso es el siguiente:
fuente
ransack
yacts-as-taggable-on
mantenerActiveRecord
intactas mis instancias.Así es como lo "manejé" si usas pluck para obtener un identificador para cada uno de los registros, unir las matrices y finalmente hacer una consulta para esos identificadores unidos:
fuente
Si tiene una serie de relaciones de registro activas y desea fusionarlas todas, puede hacer
fuente
array.inject(:merge)
no funcionó para un conjunto de relaciones de registro activo en rails 5.1.4. Pero loarray.flatten!
hizo.Fuerza bruta:
fuente