views:

370

answers:

2

I am still fairly new to rails and activerecord, so please excuse any oversights.

I have 3 models that I'm trying to tie together (and a 4th to actually do the tying) to create a permission scheme using user-defined roles.

class User < ActiveRecord::Base
  has_many :user_projects
  has_many :projects, :through => :user_projects
  has_many :project_roles, :through => :user_projects
end

class Project < ActiveRecord::Base
  has_many :user_projects
  has_many :users, :through => :user_projects
  has_many :project_roles
end

class ProjectRole < ActiveRecord::Base
  belongs_to :projects
  belongs_to :user_projects
end

class UserProject < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
  has_one :project_role
  attr_accessible :project_role_id
end

The project_roles model contains a user-defined role name, and booleans that define whether the given role has permissions for a specific task. I'm looking for an elegant solution to reference that from anywhere within the project piece of my application easily.

I do already have a role system implemented for the entire application. What I'm really looking for though is that the users will be able to manage their own roles on a per-project basis. Every project gets setup with an immutable default admin role, and the project creator gets added upon project creation.

Since the users are creating the roles, I would like to be able to pull a list of role names from the project and user models through association (for display purposes), but for testing access, I would like to simply reference them by what they have access to without having reference them by name.

Perhaps something like this?

def has_perm?(permission, user) # The permission that I'm testing
  user.current_project.project_roles.each do |role|
    if role.send(permission) # Not sure that's right...
      do_stuff
    end
  end
end

I think I'm in over my head on this one because I keep running in circles on how I can best implement this.

+1  A: 

The best way to implement this is to not implement this. I suggest using one of the many gems already created to help you with users, roles and permissions. For example:

acl9
http://github.com/be9/acl9

acl9 gives you a great little DSL you can use to add permissions and roles to users. It's really easy to set up and will save you the hassle of writing the code yourself.

acl9 works really well with clearance (http://github.com/thoughtbot/clearance) for authentication.

jonnii
I've updated the question in hopes of clarifying a bit. I have looked in to some gems, and they don't really seem to fit. The reason being that I won't be able to reference access based on the name of the role because I'm not ever going to know what the name of the role is. The name will be for display purposes only. Do you know of a gem or possibly another solution that can handle that kind of behavior? I feel that I'm close already, it's almost functional, just not very elegant. :)
Bobby
A: 

I agree with jonnii but I advice you to take a look at cancan from Ryan Bates

I think it's far simpler to implement and use.

tommasop
Cancan does not store user priveleges on the database though.
jpartogi