When I call a find with an id, it becomes a targeted find, and will throw an error RecordNotFound.
Foo::Bar.find(123) # RecordNotFound if no Bar with id 123 exists.
But when I call that with conditions, I get nil if not found:
Foo::Bar.find(:first, :conditions => [ "lower(name) = ?", name.downcase ])
I want such a conditional search to raise an error too. I know I can do:
Foo::Bar.find_by_name!("CocktailBar") #=> raises Recordnotfount if not not found.
But that has only really simple conditions. Mine need a little more complexity; actually something like:
Foo.Bar.select{ |pm| pm.name.downcase =~ /cocktail/}.first
And, if nothing is found, I want it to raise the RecordNotFound error. Is that possible at all? Or should I simply add some code to check against nil? and if nil? raise the error myself? And if so, how do I do that in Rails 3?
In the last snippet of code you are actually fetching all records from DB and then doing select
on a Ruby array. It has nothing to do with ActiveRecord
, so you can do whatever you like to raise exception manually, either use the code suggested by Douglas, or if
, or unless
etc. But it seems that you don't quite understand what your code does. Your select {...}
is not translated into SQL SELECT ... WHERE(...)
.
If you need an exception raised automatically by ActiveRecord
query, use this:
Foo::Bar.where([ "lower(name) = ?", name.downcase ]).first!
The equivalent bang methods exist for find_by methods as well, for example Foo::Bar.find_by_name!(name)
For anyone coming across this question, now you have the method find_by!
that does exactly what the OP asked for the find
case.
example:
Foo::Bar.find_by!(name: "CocktailBar")
https://apidock.com/rails/v4.0.2/ActiveRecord/FinderMethods/find_by%21
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With