Dynamic role dùng cancancan

Chắc bạn đã từng biết hoặc đã từng sử dụng cancancan trong Rails để quản lý role của user. Mình sẽ chỉ cho bạn cách dùng cancancan để tạo role dynamic. Trước hết để tạo được dynamic role dùng cancancan cần phải dùng gem gem 'cancancan' và sau đó chạy câu lệnh dưới để tạo

Chắc bạn đã từng biết hoặc đã từng sử dụng cancancan trong Rails để quản lý role của user. Mình sẽ chỉ cho bạn cách dùng cancancan để tạo role dynamic.

  • Trước hết để tạo được dynamic role dùng cancancan cần phải dùng gem
gem 'cancancan'

và sau đó chạy câu lệnh dưới để tạo model ability dùng để quản lý role

rails g cancan:ability

Bạn có thể dọc thêm tài liệu cách dùng gem cancancan tạo đây

Giả sử model một user có một role và một role có nhiều user. Trong role có quyền cho phép hoặc ko cho phép các thao tác :read, :create, :update, :destroy

Mình sẽ cần chuẩn bị code như sau:

  • User model : user thuộc một role
class User < ActiveRecord::Base
  belongs_to :role
end
  • Role model : một role gồm có nhiều user và các giá trị phần quyền sẽ được lưu dưới dạng Hash
class Role < ActiveRecord::Base
   has_many :users
   serialize :permissions, Hash
end
  • Giả sử giao diện quản lý role của bạn như ảnh dưới thì bạn có thể thao tác chỉnh sử role tùy ý.
<div class="col-md-6">
  <%= form_for [:admin, @role] do |f| %>
    <p>
      <%= f.label :name %>
      <%= f.text_field :name, class: "form-control" %>
    </p>

    <div class="row" style="justify-content: space-between; font-weight: bold;">
      <div>Function</div>
      <div>Read</div>
      <div>Create</div>
      <div>Update</div>
      <div>Destroy</div>
    </div>
    <div class="row" style="justify-content: space-between;">
      <div>Function 1</div>
      <div><%= check_box_tag "role[permissions][function1][read]" %></div>
      <div><%= check_box_tag "role[permissions][function1][create]" %></div>
      <div><%= check_box_tag "role[permissions][function1][update]]" %></div>
      <div><%= check_box_tag "role[permissions][function1][destroy]" %></div>
    </div>

    <div class="row" style="justify-content: space-between;">
      <div>Function 2</div>
      <div><%= check_box_tag "role[permissions][function2][read]" %></div>
      <div><%= check_box_tag "role[permissions][function2][create]" %></div>
      <div><%= check_box_tag "role[permissions][function2][update]" %></div>
      <div><%= check_box_tag "role[permissions][function2][destroy]" %></div>
    </div>

  <div class="row"><%= f.submit "Save", class: "btn btn-primary" %></div>
  <% end %>
</div>

  • Lúc save role vào db mình có thể thực hiện xử ly params để lưu vào dưới dạnh như
{'function1' => [:read, :create, :update], 'function2': [:read, :create, :update]}
  • Phân quyền trong model ability
class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    elsif
      user.role.permissions.each do |subject, action|
        can action,
          (klass = subject.to_s.classify.safe_constantize) ? klass : subject.to_sym
      end
    end
  end
end

Code trên sẽ tạo được role của user vd như:

can :read, Function1
can :create, Function1
can :update, Function1
can :destroy, Function1

  • Bước cuối cùng để dùng được dynamic role là trong những controller mình cần sét role phải authorize_resource của user.

Đến đây là mình có thể tạo được dynamic role dùng gem cancancan. Nó cũng không có gì quá là khó khăn. Mong giải pháp trên có thể giải quyết được vấn đề của bạn.

Tài liệu tham khảo

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ