web-dev-qa-db-ja.com

例外なく配列Rails ActiveRecordのIDを選択する方法

私のようなIDの配列があるとき

ids = [2,3,5]

そして、私は実行します

Comment.find(ids)

すべてが正常に動作します。しかし、存在しないidがある場合、例外が発生します。これは一般的に、何らかのフィルターに一致するIDのリストを取得するときに発生します。

current_user.comments.find(ids)

今回は、有効なコメントIDを持っている可能性がありますが、これは特定のユーザーに属していないため、見つからず、例外が発生します。

find(:all, ids)を試しましたが、すべてのレコードを返します。

今できる唯一の方法は

current_user.comments.select { |c| ids.include?(c.id) }

しかし、それは非常に非効率的なソリューションのように思えます。

存在しないレコードで例外を取得せずにArray in IDを選択するより良い方法はありますか?

122
Jakub Arnold

心配している例外を回避しているだけであれば、「find_all_by ..」ファミリーの関数は例外をスローすることなく機能します。

Comment.find_all_by_id([2, 3, 5])

一部のIDが存在しない場合でも機能します。これは

user.comments.find_all_by_id(potentially_nonexistent_ids)

ケースも。

更新:Rails 4

Comment.where(id: [2, 3, 5])
198

更新:この回答はRails 4.xにより関連しています

これを行う:

current_user.comments.where(:id=>[123,"456","Michael Jackson"])

このアプローチの長所は、Relationオブジェクトを返すことです。これに、さらに多くの.where句、.limit句などを結合できます。これは非常に役立ちます。また、例外をスローせずに存在しないIDを許可します。

新しいRuby構文は次のとおりです。

current_user.comments.where(id: [123, "456", "Michael Jackson"])
144
mjnissim

さらに制御が必要な場合(おそらくテーブル名を述べる必要がある場合)、次のこともできます。

Model.joins(:another_model_table_name)
  .where('another_model_table_name.id IN (?)', your_id_array)
18
Jonathan Lin

.findおよび.find_by_idメソッドはRails 4で廃止されました。そのため、代わりに以下を使用できます。

Comment.where(id: [2, 3, 5])

一部のIDが存在しない場合でも機能します。これは

user.comments.where(id: avoided_ids_array)

IDを除外するためにも

Comment.where.not(id: [2, 3, 5])
10
Sumit Munot

アプリを殺す例外を回避するには、それらの例外をキャッチし、それらを希望する方法で処理し、IDが見つからない状況でのアプリの動作を定義する必要があります。

begin
  current_user.comments.find(ids)
rescue
  #do something in case of exception found
end

Rubyの例外に関する 詳細 を次に示します。

1
rogeriopvl

他の条件を設定する場合は、named_scopeでも使用できます。

たとえば、他のモデルを含める:

named_scope 'get_by_ids'、lambda {| ids | {:include => [:comments]、:conditions => ["comments.id IN(?)"、ids]}}

0
mtfk