Adam, Have you looked at any of the roles plugins for Rails? There are several, and most of the ones I've seen and used in the past keep the roles themselves in the database. That seems a lot more practical as then permissions changes are not code changes but data changes. Since who can do what is a data issue (in my mind at least), I feel a little bit like you might be working too hard. If you need a permissions hash in each role instance why not have Role and the instances of role be Role(:name => 'users', :permissions => permission_hash) instead? Or better yet take a look at the slightly more complex but infinitely more flexible ways of doing this.
Best, Rob On Thu, Nov 19, 2009 at 13:45, Adam Grant <[email protected]> wrote: > ooooh... this one helped alot actually: > > http://railstips.org/2006/11/18/class-and-instance-variables-in-ruby > > > -- > Adam Grant > Lead Web Engineer > Telaeris, Inc. > [email protected] > (858) 627-9710 > > > On Thu, Nov 19, 2009 at 1:02 PM, Jordan Fowler <[email protected]>wrote: > >> Hey Adam, >> >> I will soon be working on exactly the same sort of code, so the timing is >> great for your post. I've done some reading on the subject of class >> inheritable variables/accessors and you may find the following very useful: >> >> http://www.raulparolari.com/Rails/class_inheritable >> http://markmail.org/message/uqv2vndtvcwqqb63 >> >> At the moment I'm going through your code and will respond with some more >> detailed notes shortly. >> >> Cheers, >> Jordan Fowler >> >> On Nov 19, 2009, at 12:21 PM, Adam Grant wrote: >> >> Hi Everyone, >> >> I have a question about meta programming, which I will get to in a bit. >> >> Below I have a little code snippet of a user roles plugin to Rails that I >> am trying to build. >> Essentially, I want to be able to define roles in "app/models/roles" that >> get loaded on Rails bootup, >> and define the permissions each role has. Por ejemplo: >> >> app/models/roles/guest.rb: >> ================= >> class Guest < Role >> permissions_for :users, {:view => true, :edit => false} >> end >> ================= >> >> Which will be able to be used like so: >> ================= >> role = User.first.role #=> Guest >> role.get_permission(:users, :view) #=> true >> ================= >> >> Now, I'd like to be able to define base role classes, and inherit/override >> their permissions for subclasses: >> ================ >> class Admin < Guest >> permissions_for :users, {:edit => true} >> end >> ================ >> >> So that I can ask the Admin role if it can view or edit users: >> ================ >> Guest.get_permission(:users, :view) #=> true >> Guest.get_permission(:users, :edit) #=> false >> >> Admin.get_permission(:users, :view) #=> true >> Admin.get_permission(:users, :edit) #=> true >> ================ >> >> The code below ALMOST accomplishes this basic functionality... >> >> *QUESTION* >> How can I get this to work? Can I utilize :attr_accessor somehow to >> replace the "def permissions" and "def permissions=" calls? >> I'm pretty sure class instance variables are what I need (so that each >> class has it's own set of permissions), but how/where to define >> the accessor methods are tripping me up. >> >> (NOTE that @permissions is a "class instance variable", not an "instance >> variable") >> >> ============================== >> class Role >> >> # Open that sweet, sweet eigenclass for some tender permissioning. >> class << self >> >> def permissions >> @permissions ||= {} >> end >> >> def permissions=(new_perms) >> permissions = new_perms >> end >> >> # Copies the parent's permissions into child as the >> # baseline permissions (inheriting the permissions, essentially). >> def inherited(child_class) >> child_class.permissions = permissions.dup >> end >> >> # Look through permissions hash for the resource and permission >> asked for. >> def get_permission(resource, permission) >> perm = permissions[resource][permission.to_sym] if >> permissions[resource] >> perm.present? ? perm : false >> end >> >> private >> >> # Define permissions for this subclass >> def permissions_for(resource, new_permissions = {}) >> permissions[resource] ||= {} >> permissions[resource].merge!(new_permissions) >> end >> end >> end >> >> ==================================== >> >> Thanks! >> - Adam >> -- >> Adam Grant >> Lead Web Engineer >> Telaeris, Inc. >> [email protected] >> (858) 627-9710 >> >> -- >> SD Ruby mailing list >> [email protected] >> http://groups.google.com/group/sdruby >> >> >> >> >> --------------------------------------------------------------- >> >> Jordan A. Fowler >> E-mail: [email protected] >> Website: http://www.jordanfowler.com >> Phone: (619) 339-6752 >> >> -- >> SD Ruby mailing list >> [email protected] >> http://groups.google.com/group/sdruby > > > -- > SD Ruby mailing list > [email protected] > http://groups.google.com/group/sdruby > -- Rob Kaufman http://notch8.com gtalk/jabber/email: [email protected] p: 858-412-7749 f: 866-477-1620 -- SD Ruby mailing list [email protected] http://groups.google.com/group/sdruby
