4

I handle RecordNotFound error in my application_controller.rb as follow:

 rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found private def record_not_found flash[:error] = "Oops, we cannot find this record" redirect_to :back end 

But I would like to get more information, such as class/table name of which record was not found. How should I go about it?

Thank you.

1
  • 1
    Indeed, it's a pity that ActiveRecord::RecordNotFound instances carry along zero information with it (class RecordNotFound < ActiveRecordError; end, end of the story). Commented Jan 10, 2013 at 11:14

4 Answers 4

4

I had some success with this:

# in app/controllers/application_controller.rb rescue_from ActiveRecord::RecordNotFound, with: :record_not_found def record_not_found exception result = exception.message.match /Couldn't find ([\w]+) with 'id'=([\d]+)/ # result[1] gives the name of the model # result[2] gives the primary key ID of the object that was not found end 

HTH

EDIT: Whitespace error removed at the end of the Regex. Thanks to the commenters. :)

Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't work. "Couldn't find EventType with 'id'=1".match(/Couldn't find ([\w]+) with 'id'=([\d]+) / returns nothing.
You need to get rid of the whitespace at the end: ..with 'id'=([\d]+)[this whitespace]/
3

You can define a parameter in your rescue handler and exception will be passed there.

def record_not_found exception flash[:error] = "Oops, we cannot find this record" # extract info from exception redirect_to :back end 

If you can't get that info from the exception, you're out of luck (I think).

5 Comments

Thanks, Sergio. Could you please give me an example of extracting info from exception?
@AdamNYC: seems like you're out of luck after all. :-)
Yeah, I checked that before I asked :)
I was hoping this was possible as well. Too bad. Seems like a ActiveRecord::RecordNotFound should at least know what it was looking for that could not be found — even if it's something as non-end-user-friendly as "WHERE id = 27" or "{id: 27}". That would help a lot in cases where you're looping through a bunch of records in a migration, for example, and trying to do where(name: name).first!.
Try this: def record_not_found exception; result = exception.to_s.match /Couldn't find ([\w]+) with 'id'=([\d]+) / ; # result[1] gives the model name; # result[2] gives the ID of the record that wasn't found; end
2

Say for example,

begin @user = User.find(params[:id]) rescue ActiveRecord::RecordNotFound flash[:notice] = "#No such record in User for id :: {params[:id]} on #{action_name}" end 

UPDATE

flash[:notice] = t('flash.recordnotfound',:class_name => self.class.name, :column_name => params[:id], :action_name => action_name) 

Now in your config/locales/en.yml (this would help translate, refer to i18n here)

flash: recordnotfound: "Sorry, no record od %{column_name} in class %{class_name} was found on you action %{action_name}" 

If you do not want to use locales just put up this information in flash[:notice] itself.

More dynamic ?

Write a function and use the same flash [:notice] there. Wont hurt at all.

want more data ?

Heres a quick solution, i always <%= params%> in my views to know easily whats going and whats coming. You can then open your rails console and play along with different actions and so on.

user = User.new user.save user.errors.messages 

All of this is good enough data, i think.

Good luck.

2 Comments

Thanks ktk. This is great, but is there a way to generalize this to work for any class?
Thank you so much for such a terrific answer! The tip is very helpful too.
0

Once you instantiate the model, you can check something like.

human = Human.new human.errors 

Check this in rails console so you could play with it and use it in the main controller.

rescue_from ActiveRecord::RecordNotFound do |exception| raise ActiveRecord, exception.message, exception.backtrace end 

EDIT Make sure you the application controller extends the base.

class ApplicationController < ActionController::Base rescue_from Exception, :with => :record_not_found private def record_not_found(e) flash[:error] = "Oops, we cannot find this record" + e.message redirect_to :back end end 

1 Comment

Thanks Claire. I got an error saying: exception class/object expected.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.