Take the 2-minute tour ×

I want to implement authorization in my Rails application on a model level (not controller), in a similar way that validation on models is done. What is the best way to do this?

If it is implemented in the models itself, the main problem is that the models don't have access to the current user. I've seen solutions like: Thread.current[:user_id] = session[:user_id], but that doesn't seem like a good idea.

I've seen a different approach where variants of the methods like create, find and new are created, accepting an additional parameter for the current user.

Another approach would be to implement all the methods in the User/role class, so for example user.posts.create or user.readable_posts.find would be used instead of Post.create or Post.find.

Which of these approaches would be suggested? Are there any better ways to implement the authorization? Are there any plugins that makes this easier? I need an approach that scales well for multiple roles and models.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I would recommend you to look at declarative authorization. It works with both models and controllers.

The way it do what you are asking is having a before_filter in the applicationController that sets Authorization.current_user = current_user where Authorization is a module.

I think that approach is the best one, it keeps the models clean and you don't have to remember to include the user everywhere, but can filter it in the models callback functions instead.

share|improve this answer
Using this approach, how are requests from the console (or any other method not going through a controller) handled? –  Ralf Nov 27 '09 at 10:53
I found the answer to my comment, Authorization::Maintenance has functionality specifically for this. At first glance declarative_authorization seemed like it missed some functionality I required, but when I looked deeper I found it to be quite powerful. I like being able to specify all the permissions in a separate file. –  Ralf Nov 27 '09 at 12:13
Yeah, it works quite well with that. Most of the logic is left out of your application. And I like the way that it actually checks if you are permitted to do something instead of listing what a user can do. It feels cleaner. –  Jimmy Stenke Nov 27 '09 at 12:26
add comment

Why would you do this? Isn't controller level identification enough?

if @user.is_able_to_do_this?

... and in your model

def is_able_to_do_this
  if self.rights > Constant::Admin_level_whatever
    return true
  return false
share|improve this answer
Mainly because I have a fairly complicated permission system, which are more complicated that just can or can't perform an action. For example, certain users should only be able to edit specific attributes of the model. –  Ralf Nov 27 '09 at 10:34
It is also simpler when the same or similar actions on a model is referenced from multiple controllers. –  Ralf Nov 27 '09 at 10:36
Ok, it makes sense. I think in that case that jimmy's answer should be a good option –  marcgg Nov 27 '09 at 11:00
add comment

Your Answer


