This morning I decided to add roles to CatchTheBest to start adding a few simple permissions to the application. Sometimes people’s eyes glaze over when they hear role-based access control, but it really doesn’t have to be complicated. There are some plugins out there that are more or less plug and play for implementing RBAC, but here’s a quick and simple example you can use in your project to easily add user roles.
First, the migration:
class CreateRoles < ActiveRecord::Migration def self.up create_table :roles do |t| t.column :name, :string end
create_table :user_roles do |t| t.column :user_id, :integer t.column :role_id, :integer t.column :created_at, :datetime end
add_index :roles, :name Role.create(:name => 'Admin')
def self.down drop_table :roles drop_table :user_roles end end
This adds the roles and user_roles tables and creates the first role (Admin). I have added an index to the name field of the roles table because we’ll be querying on that field quite a bit.
Here are the new models:
class Role < ActiveRecord::Base end class UserRole < ActiveRecord::Base belongs_to :user belongs_to :role end
There’s nothing terribly exciting there. :) Notice that I don’t have any relationship declarations in Role, as I currently don’t care about finding users by role â€” I only care about finding roles by user.
Here are the changes to the User model:
class User < ActiveRecord::Base has_many :user_roles has_many :roles, :through => :user_roles def has_role?(role) self.roles.count(:conditions => ['name = ?', role]) > 0 end
def add_role(role) return if self.has_role?(role) self.roles < < Role.find_by_name(role) end end
And that’s it. Easy, eh?