48

A user can only edit its own post, so I use the following to check if a user can enter the edit form:

  def edit
    @post = Load.find(:first, :conditions => { :user_id => session[:user_id], :id => params[:id]})
  rescue ActiveRecord::RecordNotFound
    flash[:notice] = "Wrong post it"
    redirect_to :action => 'index'
  end

But it is not working, any ideas what I am doing wrong?

ocodo
  • 29,401
  • 18
  • 105
  • 117
Adnan
  • 25,882
  • 18
  • 81
  • 110

3 Answers3

72

If you want to use the rescue statement you need to use find() in a way it raises exceptions, that is, passing the id you want to find.

def edit
  @post = Load.scoped_by_user_id(session[:user_id]).find(params[:id])
rescue ActiveRecord::RecordNotFound
  flash[:notice] = "Wrong post it"
  redirect_to :action => 'index'
end
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
53

You can also use ActionController's rescue_from method. To do it for the whole application at once!

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

  def record_not_found
    render 'record_not_found' # Assuming you have a template named 'record_not_found'
  end
end
Tim Baas
  • 6,035
  • 5
  • 45
  • 72
8

Turns out you were using rescue and find(:first) incorrectly.

find :first returns nil if no record matches the conditions. It doesn't raise ActiveRecord::RecordNotFound

try

def edit
  @post = Load.find(:first, :conditions => { :user_id => session[:user_id], :id => params[:id]})
  if @post.nil?
    flash[:notice] = "Wrong post it"
    redirect_to :action => 'index'
  end
end
EmFi
  • 23,435
  • 3
  • 57
  • 68
  • I am getting "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id" – Adnan Feb 25 '10 at 18:41
  • 1
    You were using rescue wrong, but the real problem is that find :first returns nil if no record is found. Solution updated to address the real root of your problem. – EmFi Feb 25 '10 at 18:57
  • @DemitryT: While your code would produce the same result. In this case I chose to write it this way, to explicitly address the error in the original question. Also as a matter of preference, I do not like using an assignment statement as a condition. I find the combination more difficult to maintain and debug. – EmFi Jun 08 '15 at 16:16
  • SO won't let me edit the comment, but `if @post = Load.find(:first, :conditions => { :user_id => session[:user_id], :id => params[:id]})` would evaluate to false (even if it can't find the record and Load returns nil). When it does, it can get into the else block and show the custom notice and redirect to the index action. – DemitryT Jun 08 '15 at 16:17