合并两个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