如何选择Array Rails ActiveRecord中的ID无一例外

Jak*_*old 127 activerecord ruby-on-rails find

当我有一些id,比如

ids = [2,3,5]
Run Code Online (Sandbox Code Playgroud)

我表演

Comment.find(ids)
Run Code Online (Sandbox Code Playgroud)

一切正常.但是当存在不存在的id时,我会得到一个例外.当我获得与某些过滤器匹配的ID列表时,通常会发生这种情况

current_user.comments.find(ids)
Run Code Online (Sandbox Code Playgroud)

这次我可能有一个有效的评论ID,但不属于给定的用户,所以找不到它,我得到一个例外.

我试过了find(:all, ids),但它返回了所有记录.

我现在能做到的唯一方法是

current_user.comments.select { |c| ids.include?(c.id) }
Run Code Online (Sandbox Code Playgroud)

但在我看来,这似乎是超低效的解决方案.

有没有更好的方法在Array中选择ID而不会在不存在的记录上获得异常?

pri*_*ing 203

如果它只是避免你担心的异常,那么"find_all_by .."系列函数可以在不抛出异常的情况下工作.

Comment.find_all_by_id([2, 3, 5])
Run Code Online (Sandbox Code Playgroud)

即使某些ID不存在也会有效.这适用于

user.comments.find_all_by_id(potentially_nonexistent_ids)
Run Code Online (Sandbox Code Playgroud)

案件也是如此.

更新:Rails 4

Comment.where(id: [2, 3, 5])
Run Code Online (Sandbox Code Playgroud)

  • 这将在Rails 4中弃用:http://edgeguides.rubyonrails.org/4_0_release_notes.html#active-record-deprecations (14认同)
  • 这将返回一个`Array`而不是`ActiveRecord :: Relation`,这限制了你之后可以用它做什么.`Comment.where(id:[2,3,5])`确实返回一个`ActiveRecord :: Relation`. (6认同)
  • 作为另一个扩展,如果您需要链接复杂的条件,您甚至可以做Comment.all(:conditions => ["approved and id in(?)",[1,2,3]]) (5认同)
  • @JonathanLin是正确的,mjnissim的答案应该是首选的:http://stackoverflow.com/a/11457025/33226 (3认同)

mjn*_*sim 146

更新:这个答案与Rails 4.x更相关

做这个:

current_user.comments.where(:id=>[123,"456","Michael Jackson"])
Run Code Online (Sandbox Code Playgroud)

这种方法更强大的一面是它返回一个Relation对象,你可以加入更多的.where子句,.limit子句等,这是非常有帮助的.它还允许不存在的ID而不抛出异常.

较新的Ruby语法是:

current_user.comments.where(id: [123, "456", "Michael Jackson"])
Run Code Online (Sandbox Code Playgroud)


Jon*_*Lin 20

如果您需要更多控制(可能需要声明表名),您还可以执行以下操作:

Model.joins(:another_model_table_name)
  .where('another_model_table_name.id IN (?)', your_id_array)
Run Code Online (Sandbox Code Playgroud)


Sum*_*not 10

现在.find和.find_by_id方法在rails 4中已弃用.所以我们可以在下面使用:

Comment.where(id: [2, 3, 5])
Run Code Online (Sandbox Code Playgroud)

即使某些ID不存在,它也会起作用.这适用于

user.comments.where(id: avoided_ids_array)
Run Code Online (Sandbox Code Playgroud)

也用于排除ID

Comment.where.not(id: [2, 3, 5])
Run Code Online (Sandbox Code Playgroud)

  • 在rails 4中不推荐使用https://github.com/rails/activerecord-deprecated_finders .find和.find_by_id方法. (3认同)