Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to issue a 'find' or 'where' that raises a RecordNotFound

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?

like image 761
berkes Avatar asked Mar 08 '12 11:03

berkes


2 Answers

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)

like image 162
RocketR Avatar answered Nov 11 '22 22:11

RocketR


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

like image 4
Layon Ferreira Avatar answered Nov 11 '22 20:11

Layon Ferreira