Daniel Higginbotham
2006-Jun-26 04:37 UTC
[Rails] How to limit access to model objects based on role?
Hi all,
I want to limit access to model objects based on the role of the logged in
user. It seemed the most blunt way of doing this would be make copies of
each controller which accessed the models and use one of the access control
systems out there to limit access to the controllers. However, with 9
different controllers this seems like a terrible choice.
Here''s what I''ve come up with. Each controller implements
something like the
following code. Basically, there''s a set_x_with_scope method which
takes
normal find() parameters, then passes them to X.find within X.with_scope.
So, instead of having @category = Category.find(param[:id]), which would
occur multiple times in the controller, I use
set_category_with_scope(params[:id]), which sets @category and only allows
access to data based on attributes of the current user.
Right now, I use a collection of methods to build the options for :find in
with_scope. Soon, I''m going to alter the methods so that their return
values
will depend on the user''s role. I hope all this make sense :)
On top of all this, I''m using Ezra''s access control plugin to
limit access
to the controllers.
So my question is: is there a better way to do this?
class CategoriesController < ApplicationController
access_control :DEFAULT => ''(Administrator | SuperUser)''
def edit
set_category_with_scope(params[:id])
end
def update
set_category_with_scope(params[:id])
@category.update_attributes(params[:category])
end
def set_category_with_scope(*args)
Category.with_scope(:find => scoped_options) do
@category = Category.find(*args)
end
end
def scoped_finder_conditions
@scoped_finder_conditions ||= {:conditions => "positions.company_id
#{current_user.company_id}"}
end
def scoped_finder_include
@scoped_finder_include ||= {:include => :position}
end
def scoped_options
scoped_finder_conditions.merge(scoped_finder_include)
end
Thanks!
Daniel
