合并两个ActiveRecord :: Relation对象

假设我有以下两个对象:

first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation 

是否有可能将这两个关系组合成一个包含两个条件的ActiveRecord::Relation对象?

注意:我知道我可以链接wheres得到这个行为,我真正感兴趣的是我有两个单独的ActiveRecord::Relation对象的情况。

如果要使用AND (交集)组合,请使用merge

 first_name_relation.merge(last_name_relation) 

如果你想结合使用OR (联合),使用or (在ActiveRecord 5+,或通过在哪里或回车在4.2):

 first_name_relation.or(last_name_relation) 

关系对象可以转换为数组。 这否定了之后能够使用任何ActiveRecord方法,但我并不需要。 我做到了这一点:

 name_relation = first_name_relation + last_name_relation 

Ruby 1.9,rails 3.2

merge实际上不像OR那样工作。 这只是交叉( AND

我努力解决这个问题,把ActiveRecord :: Relation对象合并成一个,我没有find任何工作的解决scheme。

我没有从这两套中寻找合适的方法来创build联合,而是集中在集合的代数上。 你可以用不同的方式用德摩根定律来做

ActiveRecord提供合并方法(AND),也可以使用not方法或none_of(NOT)。

 search.where.none_of(search.where.not(id: ids_to_exclude).merge(search.where.not("title ILIKE ?", "%#{query}%"))) 

你在这里(AüB)'= A'^ B'

更新:上面的解决scheme适用于更复杂的情况。 在你的情况下,这样的行为就足够了:

 User.where('first_name LIKE ? OR last_name LIKE ?', 'Tobias', 'Fünke') 

即使在很多奇怪的情况下,我也可以通过使用Rails的内置Arel来实现这一点。

 User.where( User.arel_table[:first_name].eq('Tobias').or( User.arel_table[:last_name].eq('Fünke') ) ) 

这通过使用Arel的或者合并两个ActiveRecord关系。


正如这里所build议的那样,合并对我来说不起作用。 它从结果中删除了第二组关系对象。

有一个名为active_record_union的gem可能是你正在寻找的。

它的例子用法如下:

 current_user.posts.union(Post.published) current_user.posts.union(Post.published).where(id: [6, 7]) current_user.posts.union("published_at < ?", Time.now) user_1.posts.union(user_2.posts).union(Post.published) user_1.posts.union_all(user_2.posts) 

如果你有一个主动logging关系的数组,并希望将它们全部合并,你可以这样做

 array.inject(:merge) 

这就是我如何处理它,如果你使用pluck来获取每个logging的标识符,将这些数组连接起来,然后对这些连接的id做一个查询:

  transaction_ids = @club.type_a_trans.pluck(:id) + @club.type_b_transactions.pluck(:id) + @club.type_c_transactions.pluck(:id) @transactions = Transaction.where(id: transaction_ids).limit(100) 

暴力吧:

 first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation all_name_relations = User.none first_name_relation.each do |ar| all_name_relations.new(ar) end last_name_relation.each do |ar| all_name_relations.new(ar) end