views:

121

answers:

1

I have a system I'm building that seems to call for some complex rules and rather than have a mess of rules through out the system. I was looking to centralize the process. (Which may not be the smartest idea I've had)

My most (perhaps least) brilliant idea was to use a seperate class to check any objects before being saved to the database against a list of allowed values in various fields. It's extremely tightly bound to the database structure but rather easily testable and easy to maintain.

Examples of rules:

  • Moderators can submit comments with moderator status but not admin status.
    • Comments.status can only be normal or moderator (admin is reserved for administrators)
  • Users can not modify moderator value on comments
    • Comments.status can only be normal, Comments.display can only be normal
  • Only moderators can suspend user accounts
    • list of numerous fields
  • Only moderators can modify other user accounts
    • restriction on which fields with logic to determine if the current user owns the row
  • Only users with paid accounts can do X, Y, and Z.

The problem I'm having is where do I put this logic. It's getting far too complex for rails validations. Implementing some of these rules is difficult or impossible if I only look at the logged in user's status. The current solution is to create a Security class that will accept a database object and a user and either allow or disallow the action to take place.

If I follow this course of action the implementation is going to be nasty. Right now I'm looking at something like this

#For every field on an object passed to Security::allow?(user, object), call this private method
def allow_helper?(user, object, field) 
    perm = permissions[user.rank][object.class.name][field] 
    if perm.is_a? Array
          perm.include? object.send(field)
    else
          perm

Which is going to very quickly become a nightmare to maintain. There has got to be an alternative to this nightmare I've dreamed up. I stopped myself before I coded this.

A: 

Why don't you create a Permissions model, and then simply see if user.permissions.find(:permission_name_here) when you design the validations and views?

Tim Sullivan
You mean something like http://github.com/DocSavage/rails-authorization-plugin/tree/master/
epochwolf
That might work, too. :-)
Tim Sullivan