当我有一组 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) }
但这在我看来是超级低效的解决方案。
有没有更好的方法来选择数组中的 ID 而不会在不存在的记录上出现异常?
如果只是避免您担心的异常,则“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])
更新:这个答案与 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"])
where
语法。我想我可能必须使用 IN
语句来编写 SQL,但这看起来更简洁,并且可以轻松替代已弃用的 scoped_by_id
。
如果您需要更多控制权(也许您需要说明表名),您还可以执行以下操作:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
your_id_array
的顺序?
ORDER BY
不起作用,因为订单不是基于属性。但是,有一种方法可以通过 SQL 来完成(所以速度很快),甚至有人为它创建了一个 gem。查看此问答:stackoverflow.com/questions/801824/…
现在 .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])
为避免异常杀死您的应用程序,您应该捕获这些异常并按照您希望的方式处理它们,在未找到 id 的情况下为您的应用程序定义行为。
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
下面是关于 ruby 异常的 more info。
如果您想在其中添加其他条件,也可以在 named_scope 中使用它
例如包括一些其他模型:
named_scope 'get_by_ids', lambda { |ids| { :include => [:comments], :conditions => ["comments.id IN (?)", ids] } }
Array
而不是ActiveRecord::Relation
,这限制了您之后可以使用它执行的操作。Comment.where(id: [2, 3, 5])
确实返回ActiveRecord::Relation
。