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