简体   繁体   中英

Rails User -> Roles -> Permissions setup

I'm working on a roles/permissions setup but can't seem to get it working as intended.

class User < ActiveRecord::Base

    has_and_belongs_to_many :roles, :join_table => "users_roles"
    has_many :permissions, :through => :roles


class Role < ActiveRecord::Base

    has_and_belongs_to_many :users
    has_and_belongs_to_many :permissions, :join_table => "roles_permissions"


class Permission < ActiveRecord::Base

    has_and_belongs_to_many :roles

What i would like is to be able to access Roles and Permissions directly from my user object (user.roles, user.permissions).

user.roles is working, but i cant seem to get user.permissions to work. Is there anyone who can help me out?

Another approach would be use plugins like Devise + CanCan. I do however have some concerns about using plugins for things as essential as authentication and authorization - what happens if they get discontinued? Anyone who has a view on this?

Thanks!

CanCan is for authorization . Authlogic and Devise are for authentication . Authorization and authentication are two different but usually related facets of a web application.

I have a feeling that you cannot use has_many :through to reference a has_and_belongs_to_many association. I think a has_many :through must reference a has_many association. I couldn't find any definitive info though. Maybe someone else knows?

I never roll my own authentication because Devise and Authlogic both do the job very well and are easy to extend (Devise especially). Best practices for secure hashing is built-in. OpenID and Facebook authentication are simple add-ons. Why re-invent the wheel? Worst case they go unsupported sometime in the future. To me that's no big deal because I still have the source code so I had nothing to loose and everything to gain.

If you don't need your permissions do be dynamic I would hard code your permissions (aka the actions that users in certain roles can perform) in to the CanCan abilities file. You probably don't need a database table for roles either, unless there is additional metadata you want to store. I recommend avoiding has_and_belongs_to_many associations because most applications will eventually require additional data be associated with the joining table. This would be one solution to consider. There are simpler and more complex ways to accomplish to same thing.

class User < ActiveRecord::Base
  has_many :roles
end

class RoleAssignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :role_assignements
  has_many :users, :through => :role_assigments
end

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.roles.include? Role.find_by_name('admin')
      can :manage, :all
    else
      can :read, :all
    end
  end
end

I think you'd be better off using CanCan to achieve authentications with roles etc.

But if you still want to access "permissions" from user model, I am guessing you can do like this in User model:

def permissions
    Permission.find(:all, :joins => {:roles => :users}, :conditions => ["users.id = ?", self.id])
  end

Haven't tested though.

You should check this out too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM