17

I am trying to make a system where user can only see articles that he or she wrote.

In Articles controller, I put below line

@article = current_user.articles.find(params[:id])

where params[:id] is an article_id.

I just want to know how I can skip the error from displaying and just redirect to the :index action if article does not exist, or if user does not have permission to view it. I put @article.nil? conditional statement after above find statement, but it seems that the find statement above produces the error immediately like below.

Couldn't find Article with ID=1662 [WHERE (articles.user_id = 1)]

How can I resolve this problem?

user482594
  • 16,878
  • 21
  • 72
  • 108
  • related to [this question](http://stackoverflow.com/questions/4966430/model-find1-gives-activerecord-error-when-id-1-does-not-exist) – rubyprince Mar 24 '11 at 03:07

4 Answers4

29

ActiveRecord::Base.find always throws an exception if it does not find a record, this is intentional. You should only use find if you absolutely expect to have whatever it is you're looking for. If you are rending a show action and can't find the article, you should rescue that exception and render a 404 (Not found) instead of redirecting to index (technically).

If you want to find something by it's id attribute without forcing an exception, use the dynamic finder find_by_id which will return false if it doesn't find a record with that id.

Edit:

Dynamic finders now have a different signature, find_by_id should now be:

find_by :id, id_to_find

See the new Rails Guide on Querying

Brett Bender
  • 19,388
  • 2
  • 38
  • 46
4

You should use find_by_id or any of the methods given in this question.

Community
  • 1
  • 1
rubyprince
  • 17,559
  • 11
  • 64
  • 104
2

The find() method raises a RecordNotFound exception, while methods such as find_by_id will return a nil value. So you have a couple options you can wrap your method call in with a begin/rescue, add a rescue_from block to your controller:

rescue_from(ActiveRecord::RecordNotFound) {|e| do something here }

or use a find_by_id method and handle the condition where nil is returned.

There are actually a number of other alternatives, but the ones above are a good start, with find_by_id probably being the easiest.

chris
  • 4,332
  • 5
  • 41
  • 61
2

This is because the ActiveRecord find method raises an exception when it can't find a specific ID. You can solve this a couple ways, the best way seems to be

begin
  @article = current_user.articles.find(params[:id])
rescue
  redirect_to articles_path
end
jaredonline
  • 2,912
  • 2
  • 17
  • 24