web-dev-qa-db-ja.com

Rails ActiveRecord:現在のユーザーを除くすべてのユーザーを検索

これは非常に簡単なはずですが、脳は短絡しています。現在のユーザーを表すオブジェクトがあり、現在のユーザーを除くすべてのユーザーを照会する場合、現在のユーザーがnilになることがあることを考慮して、これを行うにはどうすればよいですか?

これは私が今やっているものです。

def index
  @users = User.all
  @users.delete current_user
end

気に入らないのは、クエリ結果に対して後処理をしているということです。少し間違っていると感じるほか、クエリを変換してwill_paginate。クエリでこれを行う方法のための任意の提案ですか?ありがとう。

57
SingleShot

Rails 4で以下を実行できます。

_User.where.not(id: id)
_

Niceスコープでラップできます。

_scope :all_except, ->(user) { where.not(id: user) }
@users = User.all_except(current_user)
_

または、必要に応じてクラスメソッドを使用します。

_def self.all_except(user)
  where.not(id: user)
end
_

どちらのメソッドもAR関係オブジェクトを返します。これは、メソッド呼び出しを連鎖できることを意味します。

_@users = User.all_except(current_user).paginate
_

where() も配列を受け入れるため、任意の数のユーザーを除外できます。

_@users = User.all_except([1,2,3])
_

例えば:

_@users = User.all_except(User.unverified)
_

そして、他の協会を通しても:

_class Post < ActiveRecord::Base
  has_many :comments
  has_many :commenters, -> { uniq }, through: :comments
end

@commenters = @post.commenters.all_except(@post.author)
_

API Docswhere.not()を参照してください。

139
Mohamad
@users = (current_user.blank? ? User.all : User.find(:all, :conditions => ["id != ?", current_user.id]))
32
jdl

Named_scopeを作成することもできます。あなたのモデルで:

named_scope :without_user, lambda{|user| user ? {:conditions => ["id != ?", user.id]} : {} }

およびコントローラー内:

def index
  @users = User.without_user(current_user).paginate
end

このスコープは、nilで呼び出された場合はすべてのユーザーを返し、その他の場合はparamで指定されたものを除くすべてのユーザーを返します。このソリューションの利点は、この呼び出しを他の名前付きスコープまたはwill_paginate paginateメソッドと自由にチェーンできることです。

16
Jakub Kosiński

これは短いバージョンです:

User.all :conditions => (current_user ? ["id != ?", current_user.id] : [])
7
Harish Shetty

GhandaLの答えに関するメモ-少なくともRails 3では、変更する価値があります

scope :without_user, lambda{|user| user ? {:conditions => ["users.id != ?", user.id]} : {} }

(ここでの主な変更は、「id!= ...」から「users.id!= ...」になります。Rails 3)のnamed_scopeの代わりにスコープも)

元のバージョンは、単にUsersテーブルをスコーピングするだけでうまく機能します。スコープを関連付けに適用する場合(例:team.members.without_user(current_user)....)、IDの比較に使用するテーブルを明確にするために、この変更が必要でした。 SQLiteを使用せずにSQLエラーが発生しました。

個別の回答に対する謝罪...私はまだGhandaLの回答に直接コメントする評判がありません。

6
Steve Bourne

私が使用した非常に簡単なソリューション

@users = User.all.where("id != ?", current_user.id)
2
Phil Duffney

User.all.where( "id NOT IN(?)"、current_user.id)は、#<Array:0x0000000aef08f8>

User.where("id NOT IN (?)", current_user.id)
1
user3202320

User.where(:id.ne => current_user.id)

0
Lana Kushnir

あなたがそれを行うことができる別の簡単な方法:

@users = User.all.where("id NOT IN(?)", current_user.id)
0
CeeJey Official

配列がより役立つだろう

arrayID [0] = 1

arrayID [1] = 3

User.where.not(id:arrayID)

0
Asif Alam