27

In my permissions controller, I use Active record to look for a permission:

@permission = Permission.find(params[:user_id]) 

If this returns a result I then look up the permission.name And pass this to my controller.

Problem is sometimes this does returna result, othertimes it does not. When it does not, it errors. How can I prevent that from occuring?

Use Case: 1. If the user does have a permission record, show it and let the user change it 2. If not, show they don't have a permission record and allow the user to set a permission.

Thanks

5 Answers 5

55
@permission = Permission.find_by_id params[:user_id] 

The idea is that if you are using the "first param is the id" version of find, you know exactly what you are looking for, and if it isn't there, thats a problem. If you use one of the more generic finder syntaxes (like find_by_field_name), the assumption is that if it isn't there, that is an acceptable situation so just return nil.

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

1 Comment

@permission = Permission.find_by(id: params[:user_id]) now.
11

I know this is old, but I just found this and I want to suggest a different way of handling this situation. ActiveRecord::RecordNotFound is nothing to be afraid of. A user may pass in a valid record id, but that record may not belong to them (i.e. if you do something like current_user.widgets.find(params[:id])). I prefer to handle it like this:

def show begin @permission = Permission.find(params[:user_id]) rescue ActiveRecord::RecordNotFound # however you want to respond to it end end 

1 Comment

It's generally a bad idea to test by error but I gave you an upvote for showing an alternate way of doing it.
3

ActiveRecord#find with an int parameter is a targeted find. Rails raises RecordNotFound if the record isn't found.

This is different from using find with parameters like :first or :all, which is more of a search; Rails returns nil for no records in those cases. If you want to avoid the raising of an exception, use one of those options or the corresponding method names.

Example:

@permission = Permission.find(:first, :id => params[:id]) 

1 Comment

Ah, I forgot about find_by_[column]. Use that instead (see Matt Briggs' answer). It might be a little slower due to method_missing but it's more intuitive.
2

The other way:

@permission = Permission.find_all_by_id params[:user_id]

I think that it useful if user_id is a array

1 Comment

Note that find_all_by_* will be deprecated in Rails 4.
-10

I think this will work, I haven't tested it.

if @permission # Handle when the permission exists else # Handle when the permission doesn't exist end 

1 Comment

ActiveRecord#find with an int parameter is a targeted find. Rails raises RecordNotFound if the record isn't found. This is different from using find with parameters like :first or :all, which is more of a search; Rails returns nil for no records in those cases. (-1 for incorrect information and not testing)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.