如何发出引发RecordNotFound的'find'或'where'

时间:2012-03-08 11:28:48

标签: ruby-on-rails-3 activerecord

当我使用id调用find时,它将成为目标查找,并将抛出错误RecordNotFound。

Foo::Bar.find(123) # RecordNotFound if no Bar with id 123 exists.

但是当我用条件调用它时,如果没找到则会得到nil:

Foo::Bar.find(:first, :conditions => [ "lower(name) = ?", name.downcase ])

我希望这样的条件搜索也会引发错误。我知道我能做到:

Foo::Bar.find_by_name!("CocktailBar") #=> raises Recordnotfount if not not found.

但那只有非常简单的条件。我需要更多的复杂性;实际上是这样的:

Foo.Bar.select{ |pm| pm.name.downcase =~ /cocktail/}.first

并且,如果找不到任何内容,我希望它引发RecordNotFound错误。这有可能吗?或者我应该简单地添加一些代码来检查nil?如果没有?自己提出错误?如果是这样,我如何在Rails 3中做到这一点?

3 个答案:

答案 0 :(得分:45)

在最后一段代码中,您实际上是从DB获取所有记录,然后在Ruby数组上执行select。它与ActiveRecord无关,因此你可以做任何你喜欢的事情来手动引发异常,使用道格拉斯建议的代码,或if,或unless等。但似乎你不太明白你的代码是做什么的。您的select {...}未转换为SQL SELECT ... WHERE(...)

如果您需要ActiveRecord查询自动引发的异常,请使用:

Foo::Bar.where([ "lower(name) = ?", name.downcase ]).first!

find_by方法也存在等效的爆炸方法,例如Foo::Bar.find_by_name!(name)

答案 1 :(得分:3)

您的最后一段是您需要做的。检查nil,或自己提出异常。要自己提出异常,请执行以下操作:

Foo::Bar.find(:first, :conditions => [ "lower(name) = ?", name.downcase ]) || raise(ActiveRecord::RecordNotFound)

答案 2 :(得分:2)

对于遇到此问题的任何人,现在您都有方法find_by! 正是OP要求的find情况。

示例:

Foo::Bar.find_by!(name: "CocktailBar")

https://apidock.com/rails/v4.0.2/ActiveRecord/FinderMethods/find_by%21