Search code examples
ruby-on-railsaccess-rights

Where to handle user rights: in view, model or controller?


I'd like to have 3 users' groups: admins, managers and engineers. An admin can see all the objects, can change which group a user belongs and so on. A manager can see his stuff and his engineers' stuff. An engineer can see his own stuff only. The question is where to place all the logic: in a view, in a controller or in a model. I'm going to make a session helper "current_user_right_on(stuff)" and check the rights in the view:

if current_user_right_on(stuff) == view 
  show_stuff
  if current_user_right_on(stuff) == change 
    show_edit_controls
  end
end

What is the common way to do such things? What is the rule of thumb?

UPDATE So, now I have in the controller

def index
  if logged_in?
    if current_user.admin?
      @stuff = Stuff.all
    else
      @stuff = Stuff.stuff_user_can_see(current_user)
    end
  else
    @stuff = Stuff.where( <anyone can see> )
  end
end

And in the model I have method "stuff_user_can_see(user)" which selects appropriate records from the database.

What should I improve here?


Solution

  • It is currently considered a best practice to keep authorization logic at the controller level. This way, your view remains the same regardless of what role the user is because the instance variable it gets passed (e.g., @stuff) is already filtered to only show that data for which he is authorized. This will also make it easier to add an API later on if desired since the authorization logic in the controller could be reused.

    I would recommend that you first learn how to roll your own authorization before attempting to integrate a third-party authorization gem. Otherwise, you will be kind of confused as to how the gem works because you won't know what it is doing. I would check out the authorization section from Michael Hartl's Rails Tutorial book. Everything you're wanting to know is in there and explains it better than I could here.