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.