If there is no user with an id of 1 in the database, trying User.find(1)
will raise an exception.
Why is this?
If there is no user with an id of 1 in the database, trying User.find(1)
will raise an exception.
Why is this?
Because that's the way the architects intended find(id) to work, as indicated in the RDoc:
Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then RecordNotFound will be raised.
If you don't want the exception to be raised, use find_by_id, which will return nil if it can't find an object with the specified id. Your example would then be User.find_by_id(1)
.
Further to runako's explanation, it's actually pretty useful to have the choice of whether an exception is raised or not. I'm working on a blog application and I wanted to add support for viewing the next or previous blog entry. I was able to add two instance methods to my Post
model that simply return nil
when you try to get the previous post when viewing the first post, or the next post when viewing the last post:
def next
Post.find_by_id(id + 1)
end
def previous
Post.find_by_id(id - 1)
end
This avoids my helper code which conditionally generates the Previous Post/Next Post links from having to handle the RecordNotFound
exception, which would be bad because it would be using an exception for control flow.
class Post < ActiveRecord:Base
...
# Find next even with discontinuous id's
def next
self.find(:first,
:conditions => ['id > ?',id], # next than existx
:order=>'id' # this is default behaviour, you can ommit
)
end
def previous
self.find(:first,
:conditions => ['id < ?',id], # next than exists backwards
:order=>'id desc' # beware, it's a bit SLOW on MySQL
)
end
...
end
So you can do in your view more or less:
<%= link_to("next",@post.next) if @post.next %>
Hope you find useful