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::Relationobjeto 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::Relationobjetos 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::Relationtipo?mergees una intersección, no una unión.#ormé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
mergeen 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
ransackyacts-as-taggable-onmantenerActiveRecordintactas 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