Simple User Roles
# Terminal
rails g migration add_role_to_users role:integer
# AddRoleToUsers Migration
class AddRoleToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :role, :integer, default: 0, limit: 1
end
end
# models/user.rb
enum role: {
normal: 0,
admin: 1
}
# users_controller.rb
def user_params
allowed_attributes = [:email, :name]
if user_signed_in? && current_user.admin?
allowed_attributes << :role
end
params.require(:user).permit(allowed_attributes)
end
# Usage
if current_user.admin?
More Complex Example
# Terminal
rails g model role name reference access:integer
rails g model user_role user:belongs_to role:belongs_to
# CreateRoles Migration
class CreateRoles < ActiveRecord::Migration[7.0]
def change
create_table :roles do |t|
t.string :name
t.string :reference
t.integer :access, limit: 1, default: 0
t.timestamps
end
end
end
# db/seeds.rb
admin = User.create(email: "admin@example.com", password: "123456", password_confirmation: "123456")
editor = User.create(email: "editor@example.com", password: "123456", password_confirmation: "123456")
User.create(email: "guest@example.com", password: "123456", password_confirmation: "123456")
admin_user_role = Role.create(name: "Admin User", reference: "User", access: :createable)
admin_post_role = Role.create(name: "Admin Post", reference: "Post", access: :createable)
editor_post_role = Role.create(name: "Editor Post", reference: "Post", access: :editable)
admin.user_roles.create(role: admin_user_role)
admin.user_roles.create(role: admin_post_role)
editor.user_roles.create(role: editor_post_role)
# models/role.rb
class Role < ApplicationRecord
has_many :user_roles, dependent: :destroy
enum access: {
viewable: 0,
createable: 1,
editable: 2,
no_access: 3
}
end
# models/user_role.rb
class UserRole < ApplicationRecord
belongs_to :user
belongs_to :role
end
# models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :user_roles, dependent: :destroy
has_many :roles, through: :user_roles
def can_edit?(resource)
resource_class = resource.class.to_s == "Class" ? resource.name : resource.class.to_s
role = roles.where(reference: resource_class)
return false unless role
role.map(&:editable?).any? || role.map(&:createable?).any?
end
def can_create?(resource)
resource_class = resource.class.to_s == "Class" ? resource.name : resource.class.to_s
role = roles.where(reference: resource_class)
return false unless role
role.map(&:createable?).any?
end
end
# Rails Console
user.can_edit?(post)
user.can_create?(post)
user.can_edit?(Post)
user.can_create?(Post)
# helpers/application_helper.rb
module ApplicationHelper
def can_edit?(resource)
return false unless user_signed_in?
current_user.can_edit?(resource)
end
def can_create?(resource)
return false unless user_signed_in?
current_user.can_create?(resource)
end
end
# views/posts/index.html.erb
<%= link_to "Edit", edit_post_path(post) if can_edit?(post) %>