12

次のように、同じモデルでレコードを保持する 2 つのリレーションがあるとします。

@companies1 = Company.where(...)
@companies2 = Company.where(...)

これら 2 つの関係の交点、つまり、両方の関係にある会社のみを見つけるにはどうすればよいですか?

4

5 に答える 5

12

デフォルトでは、これらwhereを一緒に接続すると AND が作成されますが、これはあなたが望むものです。

多くは次のとおりです。

class Company < ActiveRecord::Base
  def self.where_1
    where(...)
  end
  def self.where_2
    where(...)
  end
end

@companies = Company.where_1.where_2

====== 更新 ======

次の 2 つのケースがあります。

# case 1: the fields selecting are different
Company.where(:id => [1, 2, 3, 4]) & Company.where(:other_field => true)
# a-rel supports &, |, +, -, but please notice case 2

# case 2
Company.where(:id => [1, 2, 3]) & Company.where(:id => [1, 2, 4, 5])

# the result would be the same as
Company.where(:id => [1, 2, 4, 5])
# because it is &-ing the :id key, instead of the content inside :id key

したがって、ケース 2 の場合は、@apneadiving がコメントしたようにする必要があります。

Company.where(...).all & Company.where(...).all

もちろん、これを行うと 2 つのクエリが送信され、おそらく必要以上の結果がクエリされます。

于 2011-06-22T05:52:23.967 に答える
7

SQL キーワード INTERSECT を使用します。

params1 = [1,2,4]
params2 = [1,3,4]
query = "
SELECT companies.* FROM companies
WHERE id in (?,?,?)
INTERSECT
SELECT companies.* FROM companies
WHERE id in (?,?,?)
"
Company.find_by_sql([query, *params1, *params2])

以前のソリューションよりも高速になります。

于 2012-07-02T19:08:25.813 に答える
1

あなたが使用することができますActiveRecord::SpawnMethods#merge

例:

Company.where(condition: 'value').merge(Company.where(other_condition: 'value'))
于 2015-10-07T11:03:06.577 に答える