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
