Reputation: 1879
In my current rails program when I use something like
user = User.find(10)
When there is no user with ID=10 , I will have exception like :
ActiveRecord::RecordNotFound: Couldn't find User with ID=10
Can I get nil instead of raising exception so when I do something like :
unless user = Challenge.find(10)
puts "some error msg"
end
I just want to get nil when there is no records and I don't want to use begin/rescue
Thanks
Upvotes: 128
Views: 63547
Reputation: 1282
For those struggling with mongoid, it turns out that both find
and find_by
methods will raise exception - no matter your rails version!
There is an option (namely raise_not_found_error) which can be set to false, but when falsey makes find
method doesn't to raise exception as well.
Thus the solution for mongoid users is the disgusting code:
User.where(id: 'your_id').first # argghhh
Upvotes: 4
Reputation: 115511
Yes, just do:
Challenge.find_by_id(10)
For Rails 4 and 5:
Challenge.find_by(id: 10)
Upvotes: 221
Reputation: 337
You can use find_by with the required attribute (in your case the id) this will return nil instead of giving an error if the given id is not found.
user = Challenge.find_by_id(id_value)
or you could use the new format:
user = Challenge.find_by id: id_value
You could also use where but you have to know that where return an active record relation with zero or more records you need to use first to return only one record or nil in case zero records return.
user = Challenge.where(id: id_value).first
Upvotes: 1
Reputation: 1809
Why don't you simply catch the exception? Your case looks exactly like what exceptions were made for:
begin
user = User.find(10)
rescue ActiveRecord::RecordNotFound
puts "some error msg"
end
If you want to recover from the error in the rescue block (e.g. by setting a placeholder user (null pattern)), you can continue with your code below this block. Otherwise you might just put all your code for the "happy case" in the block between "begin" and "rescue".
Upvotes: 5
Reputation: 683
In Rails 4, dynamic finders - such as find_by_id
which was used in the accepted answer - were deprecated.
Moving forward, you should use the new syntax:
Challenge.find_by id: 10
Upvotes: 37
Reputation: 1448
you can do this a bit hackish, just use the ActiveRecord Query Interface.
this will return nil, instead of raising a Exception
User.where(:id => 10).first
Upvotes: 18