当我有一系列ID时,比如
ids = [2,3,5]
我执行
Comment.find(ids)
一切正常。但是当存在不存在的id时,我会得到一个例外。当我得到与某些过滤器匹配的ID列表而不是像这样的ID时,通常会发生这种情况
current_user.comments.find(ids)
这次我可能有一个有效的评论ID,但不属于给定的用户,因此找不到,我得到例外。
我尝试了find(:all, ids)
,但它会返回所有记录。
我现在能做到的唯一方法是
current_user.comments.select { |c| ids.include?(c.id) }
但在我看来,这似乎是超低效的解决方案。
有没有更好的方法在数组中选择 ID而不会在不存在的记录上获得异常?
答案 0 :(得分:194)
如果它只是避免你担心的异常,那么“find_all_by ..”系列函数可以正常工作而不会抛出异常。
Comment.find_all_by_id([2, 3, 5])
即使某些ID不存在,也能正常工作。这适用于
user.comments.find_all_by_id(potentially_nonexistent_ids)
案例。
Comment.where(id: [2, 3, 5])
答案 1 :(得分:143)
更新:此答案与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"])
答案 2 :(得分:18)
如果您需要更多控制(可能需要说明表名),您还可以执行以下操作:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
答案 3 :(得分:10)
现在.find和.find_by_id方法在rails 4中已弃用。所以我们可以在下面使用:
Comment.where(id: [2, 3, 5])
即使某些ID不存在,它也能正常工作。这适用于
user.comments.where(id: avoided_ids_array)
还要排除ID&#39>
Comment.where.not(id: [2, 3, 5])
答案 4 :(得分:1)
为了避免异常查杀您的应用,您应该捕获这些异常并按照您希望的方式对待它们,在未找到ID的情况下为您的应用定义行为。
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
以下是关于ruby异常的more info。
答案 5 :(得分:0)
如果你想把其他条件放在
,你也可以在named_scope中使用它例如包括一些其他模型:
named_scope'get_by_ids',lambda {| ids | {:include => [:comments],:conditions => [“comments.id IN(?)”,ids]}}