Suponha que eu tenha os dois objetos a seguir:
first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation
é possível combinar as duas relações para produzir um ActiveRecord::Relation
objeto contendo as duas condições?
Nota: Estou ciente de que posso encadear os caminhos para obter esse comportamento. O que realmente me interessa é o caso em que tenho dois ActiveRecord::Relation
objetos separados .
ruby-on-rails
rails-activerecord
arel
Patrick Klingemann
fonte
fonte
Respostas:
Se você deseja combinar usando
AND
(interseção), usemerge
:Se você deseja combinar usando
OR
(união), use † :or
† Somente no ActiveRecord 5+; para 4.2 instale o where-ou backport.
fonte
ActiveRecord::Relation
tipo?merge
é uma interseção, não união.#or
método foi adicionado ao ActiveRecord :: Relation em janeiro de 2015 e fará parte do Rails 5.0 , que será lançado no final de 2015. Ele permite o uso do operador OR para combinar cláusulas WHERE ou HAVING. Você pode fazer o checkout do HEAD se precisar antes do lançamento oficial. Veja a solicitação de mesclagem # 16052 @Arcolye @AndrewMarshall @ Aldo-xoen-GiambellucaObjetos de relação podem ser convertidos em matrizes. Isso nega a possibilidade de usar qualquer método ActiveRecord neles posteriormente, mas eu não precisava. Eu fiz isso:
Ruby 1.9, trilhos 3.2
fonte
merge
na verdade não funciona comoOR
. É simplesmente interseção (AND
)Lutei com esse problema para combinar os objetos ActiveRecord :: Relation em um e não encontrei nenhuma solução funcional para mim.
Em vez de procurar o método certo para criar uma união a partir desses dois conjuntos, concentrei-me na álgebra de conjuntos. Você pode fazer isso de maneira diferente usando a lei de De Morgan
O ActiveRecord fornece o método de mesclagem (AND) e você também não pode usar o método ou none_of (NOT).
Você tem aqui (A u B) '= A' ^ B '
ATUALIZAÇÃO: A solução acima é adequada para casos mais complexos. No seu caso, basta isso:
fonte
Consegui fazer isso, mesmo em muitas situações estranhas, usando o Arel interno do Rails .
Isso mescla as relações ActiveRecord usando Arel ou .
A mesclagem, como foi sugerido aqui, não funcionou para mim. Ele retirou o segundo conjunto de objetos de relação dos resultados.
fonte
Existe uma gema chamada active_record_union que pode ser o que você está procurando.
Seu exemplo de uso é o seguinte:
fonte
ransack
eacts-as-taggable-on
manterActiveRecord
intactas minhas instâncias.Foi assim que eu "lidei" com isso, se você usar o pluck para obter um identificador para cada um dos registros, juntar as matrizes e, finalmente, fazer uma consulta para esses IDs:
fonte
Se você tiver uma série de relações de registros de ativos e quiser mesclar todas elas, poderá fazer
fonte
array.inject(:merge)
não funcionou para uma série de relações de registros de ativos nos trilhos 5.1.4. Masarray.flatten!
fez.Força bruta:
fonte