Use your favourite class variable pattern and then do
self.class.permitted_actions or whatever you call it.
Fred
Hi Fred.
Funny enough, when I initially wrote “Hello all”, I mused to myself that
I should probably just write “Hello Fred”. Heh heh.
Thanks for the instruction. You are a quite a help to a lot of people. I
was watching the Ruby Hero awards the other day, and was thinking that
you deserve one of those as well. Cheers to you!
Now, if I could pick your (or anyone else’s for that matter) brain a bit
more, I’m having another problem with my access scheme. The original
post was just generalities, so I’ll use specific code this time.
In application.rb, I have
class ApplicationController < ActionController::Base
extend RoleAccess
init_role_access
protected
def require_access
redirect_to person_path unless verify_access(@current_person)
end
end
and in an actual controller, this
class SportsController < ApplicationController
permit_access(:system_administrator)
permit_access(:oranization_administrator, [:index, :show, :update])
permit_access(:sport_administrator, [:show, :update])
before_filter :require_logged_in
before_filter :require_access
…
end
and finally, lib/role_access.rb looks like
module RoleAccess
def init_role_access
include InstanceMethods
extend ClassMethods
@@access_map ||= {}
end
def self.access_map
@@access_map
end
module ClassMethods
def permit_access(*args)
access_map = RoleAccess::access_map
#debugger
controller = self.controller_name.to_sym
#********************************************
# Problem with next line, see comment below
all_actions = self.action_methods.collect { |action| action.to_sym
}
#********************************************
options = args.last.is_a?(Hash) ? args.pop.symbolize_keys : {}
by = args.first.is_a?(Array) ? args.first : [args.first]
return if by.size.zero?
if options.has_key?(:only)
only = options[:only] || []
to = all_actions.select { |a| only.include?(a) }
elsif options.has_key?(:except)
except = options[:except] || []
to = all_actions.delete_if { |a| except.include?(a) }
end
to ||= all_actions
return if to.size.zero?
access_map[controller] = {} unless access_map.has_key?(controller)
to.each do |action|
access_map[controller][action] = [] unless
access_map[controller].has_key?(action)
by.each do |role|
access_map[controller][action] << role unless
access_map[controller][action].include?(role)
end
end
end # permit_access
end # module ClassMethods
module InstanceMethods
protected
def verify_access(current_person)
#debugger
access_map = RoleAccess::access_map
controller = controller_name.to_sym
action = action_name.to_sym
# if the controller is not explicitly listed, allow access
return true unless access_map.has_key?(controller)
# if the action is not explicitly listed, allow access
return true unless access_map[controller].has_key?(action)
# if we get here, the controller and action are both in
access_map…check to see
# if the user can access the action
roles = access_map[:controller][:action]
roles.each do |role|
role_method = “#{role}?”
return true if current_person.respond_to?(role_method) &&
current_person.send(role_method)
end
return false
end # verify_access(current_person)
end # module InstanceMethods
end
My intent, if it’s not clear, is to grant access to all the actions to
system administrators, and access to selected actions to organization
and sport administrators. It appears that sharing @@access_map is now
working, but the problem I am now having relates to the line indicated
above:
all_actions = self.action_methods.collect { |action| action.to_sym }
If I comment out all of the lines related to loading RoleAccess (as if
it never existed) and go into script/console,
SportController.action_methods returns
SportsController.action_methods
=> #<Set: {“edit”, “delete”, “show”, “new”, “update”, “destroy”,
“index”, “create”}>
When trying to use RoleAccess and debugging the aforementioned line, I
see that self is SportsController, yet action_methods returns an empty
set.
/Users/phillip/dev/projects/sports/sports_dev/lib/role_access.rb:17
controller = self.controller_name.to_sym
(rdb:27) p self
SportsController
(rdb:27) p self.respond_to?(:action_methods)
true
(rdb:27) p self.action_methods
#<Set: {}>
(rdb:27) p SportsController.action_methods
#<Set: {}>
(rdb:27)
So the long and short of it is when I don’t pass any actions in the call
permit_access(:system_administrator)
I want to grab all of the actions dynamically, but the fact that
self.action_methods is empty results in the system administrator being
granted access to nothing.
Ideas?
Peace,
Phillip