Railsモデルは等しくない場所を見つける


127

等しくない条件でデータベース内のレコードを検索するにはどうすればよいですか?私はこれを今持っていますが、それを行うための空想的なレールスピークの方法はありますか?

GroupUser.where('user_id != ?',me)

あなたが持っているものはそれを行うためのかなり良いRails 3の方法です。
Spyros

回答:


229

Rails 4.xの場合(http://edgeguides.rubyonrails.org/active_record_querying.html#not-conditionsを参照)

GroupUser.where.not(user_id: me)

Rails 3.x

GroupUser.where(GroupUser.arel_table[:user_id].not_eq(me))

長さを短くするにGroupUser.arel_tableは、変数に格納するか、モデルGroupUser自体の内部(たとえば)でscope使用する場合arel_table[:user_id]は、GroupUser.arel_table[:user_id]

Rails 4.0構文は@jbeardenの答えに貢献しています


協会ではどうですか?-has_many:group_users、-> {where.not(status: "Declined")}、through::groups、foreign_key: "user_id"
ajbraus

4
注意点として、それもうまく動作しますチェーン:GroupUser.where(other_condition: true).where.not(user_id: user_id)
エンリコ・Carlesso


26

より洗練された方法は、MetaWhereを使用することです。

MetaWhereには、次のようなコードを許可するSqueelと呼ばれる新しいいとこがあります。

GroupUser.where{user_id != me}

言うまでもなく、これが唯一のリファクタリングである場合は、gemを使用する価値はなく、取得したものに固執します。Squeelは、Rubyコードとやり取りする複雑なクエリが多数ある状況で役立ちます。


4
MetaWhereはすばらしいですが、このタスクは宝石を追加しなくても実行できます。
tybro0103 2012年

1
@ tybro0103もちろん、タスクを実行できます(OPの実行方法は完全に問題ありません)。ですから、宝石なしでもっと上手にできると思うなら、私はその方法に非常に興味があります。
Jakub Hampl

Vikrantの答えは、SQLや他のgemを含まないソリューションを提供します。しかし、私は正直に言います、あなたの答えは間違いなく最もコーダーに優しい/空想です。
tybro0103

1
そのような単純なタスクを実行するために宝石を追加します。バズーカで
モジー

これはやりすぎです。
コートシマ

23

Rails 4:

not equalとequalの両方を使用する場合は、以下を使用できます。

user_id = 4
group_id = 27
GroupUser.where(group_id: group_id).where.not(user_id: user_id)

さまざまな演算子(つまり><)を使用する場合は、ある時点で表記法を次のように切り替えることができます。

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)

どうGroupUser.where(group_id: group_id).where.not(user_id: user_id)ですか?
Enrico Carlesso 2014

@EnricoCarlesso投稿ありがとうございます。私はあなたの提案を含めるために私の答えを更新しました。ありがとう。
リック・スミス

9

関連付けを処理するときは、常に SQLクエリにテーブル名を含める必要あります。

実際、別のテーブルにuser_id列があり、両方のテーブルを結合すると、SQLクエリにあいまいな列名が含まれます(トラブルなど)。

したがって、あなたの例では:

GroupUser.where("groups_users.user_id != ?", me)

またはもう少し詳細:

GroupUser.where("#{table_name}.user_id IS NOT ?", me)

ハッシュを使用している場合は、Railsがハッシュを処理するため、そのことを心配する必要はありません。

GroupUser.where(user: me)

Rails 4では、@ dr4k3で述べたように、queryメソッドnotが追加されました。

GroupUser.where.not(user: me)

6

Rails 3では、もっと奇妙なことは何も知りません。ただし、ご存知かどうかはわかりませんが、等しくない条件が(user_id)NULL値と一致しません。それが必要な場合は、次のようにする必要があります。

GroupUser.where("user_id != ? OR user_id IS NULL", me)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.