2016-04-07 10 views
1

特定の値に関連するすべてのレコードを持っていないレコードを検索名前は「記録されました」(タグがないユーザーも必要です)。ユーザーの関係を考えると、私はこれを持っています:私はモデルのカップルを持っている

users.joins("LEFT OUTER JOIN user_tags ON user_tags.user_id = users.id AND user_tags.name = 'recorded'"). 
where(user_tags: { id: nil }) 

これを行うには他にも優れた方法がありますか?

+0

ちょっと答えが追加されました –

+0

あなたが今までに得たものは、おそらくあなたが必要とするものを得る最もクリーンなアプローチだと思います。 – jeffdill2

答えて

2

これを試してみてください:

users.joins("LEFT OUTER JOIN user_tags ON user_tags.user_id=users.id").where("user_tags.name != ? OR user_tags.id is NULL", 'recorded') 
+0

我々は同じアイデアを1分ごとに得ました:D – born4new

+0

これは、タグを持たないユーザーを返しません。 –

+0

@HommerSmith私は答えを更新しました。左テーブルから、関連していないか、条件を満たすすべてのレコードを返します。 – dp7

1

この1は動作するはずです:

users.joins(:user_tags).where.not(user_tags: { name: 'recorded' }) 
+0

これはタグを持たないユーザーを返しません –

+0

あなたは左の結合を維持し、上のクエリでそれに応じて置き換える必要があります。 – born4new

+0

@ born4あなたはeager_loadを使用するには左外部結合に最適です。 –

0

は、それが0 user_tagsをユーザーに返します、これを試してみてください:

users = users.joins(:user_tag).where("users.id IN (?) OR user_tags.name != ?",User.joins(:user_tag).group("users.id").having('count("user_tag.user_id") = 0'), "recorded") 
0

は、ネストされた熱心な負荷ではない参加モデルには "Includes or eage_load"を使用する必要があります

users.eager_load(:user_tags).where.not(user_tags: { name: 'recorded' }) 

これは左外部結合を使用し、where句でクエリを更新できます。 同じ

として
users.includes(:user_tags).where.not(user_tags: { name: 'recorded' }) 
0

ねえあなたは、単にすべてのレコードUSER_TAG名前を持つuser_tagsuser_tags.name != 'recorded'戻りレコードを持っていないuser_tags.id is nullリターンとして外部結合のためのincludesを使用することができますすることはrecorded

users.includes(:user_tags).where("user_tags.id is null or user_tags.name != ?","recorded") 

されていないか、またはあなたはまた、使用することができますnot in句を使用しますが、指定されたクエリに対して最適化された方法はありません:

users.includes(:user_tags).where("users.id not in (select user_id from user_tags) or user_tags.name != ?","recorded") 
+0

'!= 'recorded''これはセキュリティ上の問題を引き起こします。 –

関連する問題