2013-01-07 10 views
11

私はクライアントモデルと、クライアントが多くのプロダクトを持ち、プロダクトがCLientに属しているプロダクトモデルを持っています。Rails ActiveRecordは関連テーブルにidが存在するレコードを返します

は、私は彼らが

クライアントテーブル

id |  name 
-------------- 
1 | Company A 
2 | Company B 
3 | Company C 

製品テーブル

id |  name | client_id 
--------------------------- 
1 | Product A |   1 
2 | Product B |   1 
3 | Product C |   3 
4 | Product D |   3 
5 | Product E |   1 

私は必要クライアント1 Productテーブル内のレコードを持っている場合にのみクライアントを返すクエリを見つける必要があります3

たとえば、

のようなもの
@clients = Client.where("client exists in products") #something to this effect 
+0

は '@clientsを行います= Client.joins(:products) 'は動作しますか?私はそれがあなたが望んでいる(私は思う)内なるジョインを行うと思います – pjam

+0

それは良い質問です、私はコンソールでテストします – ctilley79

+0

@pjamそれはすべての製品をクライアントに参加して返されるようですので、重複したクライアント名。結果をクライアントに限定する方法はありますか? – ctilley79

答えて

17

最も簡単ではなく、最速:

Client.where(:id => Product.select(:client_id).map(&:client_id)) 

SQLのサブクエリ(より速い):

Client.where("EXISTS(SELECT 1 from products where clients.id = products.client_id)") 
+0

これははるかに良い答えです。 – ctilley79

+0

私は本当にこの答えが好きです。 2番目のクエリでは、同じDB内にある非アクティブレコードテーブルと比較することができます。 – BaneOfSerenity

5

はここで別のソリューションです。これは、ヴァレリーの第二の溶液のようなサブクエリのですが、SQLを記述することなく:ここ

Client.where(Product.where(client_id: Client.arel_table[:id]).exists) 
+0

これは私のためには機能しません(postgresqlアダプタを使用)。準備された値としてarel_table paramを解釈し続け、それが1ではないのでエラーになります。 – hoffmanc

+1

私は、 '.exists'がパブリックAPIの一部ではないことを知りました。これまでは4.1まで動作していましたが、4.2では動作しませんでした。 – svoop

6

Where Exists宝石(:私はその作者だ開示):使用するソリューションです

Client.where_exists(:products) 
+1

素敵な宝石!エレガントに見える! –

+0

素晴らしい仕事、ありがとう! –

関連する問題