2017-10-19 21 views
0

タイトルを説明しましょう。Rails 5 - ActiveRecord - 空の値を含む、除外するhas_manyリレーションをフィルタリングする

私は例えばので、すべてのモデルAの

を示しながら、日付の月と年によってモデルBをフィルタリングするにhas_manyモデルB.

というモデルA持っている:

A1を - > 3旅館

A2 - > 0旅館

A3 - > 1 B

これは私の今のクエリです:

A.includes(:b_relation) 
.where("extract(month from b.date) = #{month}").references(:b_relation) 
.where("extract(year from b.date) = #{year}").references(:b_relation) 
.all 

それは動作します!しかし、それは私に少なくとも1つのBを持っているAを与えるだけです。誰も持っていないAは表示されません。

Bを持たないモデルAをクエリに含めるにはどうすればよいですか?

答えて

1

INNER JOINのクエリでは、Aのレコードには、Bが関連付けられていません。あなたが欲しいのは、LEFT OUTER JOIN -aka a LEFT JOINです。左結合には、関連テーブルの関連レコードがあるかどうかにかかわらず、親テーブルのすべての行が含まれます。私は常にSQLを可視化するため、この画像が役立つ

は、種類に参加:

enter image description here

Railsは5は、このためのleft_outer_joinsmethodを持っている(別名:left_joins):以前のバージョンの

A.left_outer_joins(:b_relation) 

Rails、それはもっと手作業です(私はここでテーブル名を作ります):

A.joins('LEFT OUTER JOIN "bs" ON "bs"."a_id" = "as"."id"') 
+0

クエリを実行した場合、内部的にインクルードすると 'eager_load' ActiveRecordメソッドを使用するため、LEFT OUTER JOINを実行します。既にLEFT OUTER JOINを使用しています – Lokuzt

+0

ARクエリによって生成されたSQLを共有できますか? 。。COLUMNS "B"、 "ID" t1_r0、 AS - - FROM は "" LEFT OUTERは "B" を登録しよBのCOLUMNSこの SELECT "A" のような "ID" t0_r0、 はAS – hoffm

+0

何か ON "B" "a_id" = "A"。 "id" \t "A" "blabla_id" = 'cfa7e8a8-5566-4ce7-bcbc-05cf420cf7d1' \t AND((Extract(month FROM B.date)= 10) \t AND(抽出FROM Bの日付)= 2017)またはB.date IS NULL) – Lokuzt

関連する問題