6

In my edit action, I have

@item = current_user.shop.items.find(params[:id])

So that the user can only edit items that belong to their shop. If they try to edit an item that does not belong to their shop, then they get an ActiveRecord::RecordNotFound error.

What is the best way of handling this error in situations like this? should i raise an exception? should i redirect somewhere and set the flash (if so, how do i do that), should i just leave it as is? Any advice is appreciated.

Thanks

pingu
  • 8,719
  • 12
  • 50
  • 84

3 Answers3

22

+1 for the solution of @Koraktor. If you want to avoid ActiveRecord::RecordNotFound, you can use find_by method instead of find.

@item = current_user.shop.items.find_by_id(params[:id])
if @item.nil?
  flash[:error] = "Item not found"
else
  # Process the @item...
end
Blue Smith
  • 8,580
  • 2
  • 28
  • 33
22

Add something like the following to your controller:

rescue_from ActiveRecord::RecordNotFound do
  flash[:notice] = 'The object you tried to access does not exist'
  render :not_found   # or e.g. redirect_to :action => :index
end
Koraktor
  • 41,357
  • 10
  • 69
  • 99
5

Additionally you should set the http status while rendering the template :

rescue_from ActiveRecord::RecordNotFound do
  render :not_found, :status => :not_found
end

Check the Rails guide (section 2.2.13.4) for the status list.

As stated somewhere else (for example here ) you should never make a redirection when sending a 40x status, only 30x statuses should allow redirecting. So you may encounter a weird "You are being redirected" page whenever trying to make a redirect with a :not_found status.

Community
  • 1
  • 1
demental
  • 1,444
  • 13
  • 25