before_filter :login_required
# ... the controller
private
def authorized?
logged_in? && current_user.administrator?
end
Refactorings
No refactoring yet !
jamesgolick
September 27, 2007, September 27, 2007 10:41, permalink
So, I added this
def self.requires_role(role)
before_filter :login_required
send(:define_method, :authorized?) do
logged_in? && current_user.send("#{role}?")
end
end
requires_role :administrator
macournoyer
September 27, 2007, September 27, 2007 10:45, permalink
Really good idea James, but what if some actions require admin, other to be the author and stuff like that ?
macournoyer
September 27, 2007, September 27, 2007 11:43, permalink
What about this:
def self.requires_role(role, options={})
before_filter(options) { logged_in? && current_user.send("#{role}?") ? true : access_denied }
end
require_role :admin, :only => [:destroy] require_role :author, :except => [:index, :show]
jamesgolick
September 27, 2007, September 27, 2007 11:56, permalink
Problem is, that block seems to get called at the class's scope. The controller is passed to it, but all those methods are protected. Send hack to the rescue!
NoMethodError: undefined method `logged_in?' for ProductsController:Class
def self.requires_role(role, options={})
before_filter(options) { |controller| controller.send(:logged_in?) && controller.send(:current_user).send("#{role}?") ? true : controller.send(:access_denied) }
end
jamesgolick
September 27, 2007, September 27, 2007 11:59, permalink
Marc's suggestion. Which one does everybody like better?
def self.requires_role(role, options={})
before_filter(options) { |controller| controller.instance_eval { logged_in? && current_user.send("#{role}?") ? true : controller.access_denied } }
end
jamesgolick
September 27, 2007, September 27, 2007 12:06, permalink
As an aside, it's helpful to have this in your user model, if you want current_user.send("#{role}?") to work
ROLES = %w( administrator staff )
ROLES.each do |current_role|
send(:define_method, "#{current_role}?") do
self.role == current_role
end
end
macournoyer
September 27, 2007, September 27, 2007 12:30, permalink
I don't think you need the send on define_method if you're doing this in the class. It's a class method.
This is a couple of lines that I was writing a lot