Sử dụng gem Pundit trong ứng dụng rails

Khi được giao cho làm một chức năng liên quan đến phân quyền. Mình bị comment và được suggest sử dụng Pundit. Lúc đấy cũng thắc mắc tự hỏi, sao lại dùng nó làm gì nhỉ, dùng thì được lợi ích gì chứ? Cũng từ lúc ấy, mình mới bắt đầu tìm hiểu về Pundit là gì? Dùng như thế nào và tại sao lại nên dùng nó?

Phạm vi bài viết này giới thiệu chung về gem Pundit, cách sử dụng cũng như tìm hiểu lý do chúng ta nên dùng Pundit khi làm những chức năng liên quan đến phân quyền người dùng.

1. Giới thiệu

Pundit cung cấp một bộ helpers hướng dẫn bạn sử dụng các class Ruby thông thường và các mẫu thiết kế hướng đối tượng để xây dựng một hệ thống ủy quyền đơn giản, mạnh mẽ và có thể mở rộng.

2. Cài đặt

Cho vào gem file và sau đó chạy lệnh bundle install ở trên command line.

gem "pundit"

3. Cách sử dụng

Trước hết cần include Pundit vào trong controller của ứng dụng

class ApplicationController < ActionController::Base
  include Pundit
  protect_from_forgery
end

Sau đó, có thể chạy lệnh bên dưới hoặc có thể tự tạo bằng tay để tạo ra một folder app/policies:

rails g pundit:install

Bây giờ chúng ta sẽ cùng tìm hiểu rõ hơn, thông qua một ví dụ: Chẳng hạn khi muốn thiết lấp quyền chỉ quản trị viên của trang mới được đăng bài, thì ta có thể dùng Policy như sau:

  • Muốn sử dụng policy cho đối tượng nào chúng ta sẽ vào folder app/policies để tạo một file tương ứng với đối tượng và controller của nó. Và tất cả những xử lý liên quan đến cấp truyền gì ta cũng sẽ xử hết trong này.

Với ví dụ phía trên: Ta có một đối tượng là Post ta sẽ tạo policy tương ứng như bên dưới:

//post_policy.rb

class PostPolicy
  attr_reader :user, :post

  def initialize user, post
    @user = user
    @post = post
  end

  def publishable?
    user.admin?
  end
end
  • Phía controller thì ta có thể gọi như sau:
//post_controller.rb
    def update
      @post = get_post
      policy(current_user, @post).puslisable?
      //do something
    end
    
    def get_post
    end
  • Ngoài ra, còn có cách gọi khác: Ở post_policy.rb, bạn chỉ cần tạo ra những method tương ứng với những action ở phía controller như sau:
  def show?
    post.showable? user
  end

  def edit?
    post.editable? user
  end

  def update?
    user.admin?
  end
  • Thì lúc này, ta sẽ gọi bên controller như sau:

def show
  authorize @post
end

def update
  authorize @post
end 
  • Khi muốn gọi gọi method ở policy phía controller, mà method đó không map vs action nào, ta có thể gọi như sau:
def update
  @post = get_post
  authorize @post, :pusblishabel?
//do something
end

Từ ví dụ trên, ta có thể thấy:

  • Dùng Policy cũng chỉ là tạo ra một class Ruby đơn thuần, bằng việc gộp những thao tác xử lý quyền... vào trong class đấy.
  • Policy ở đây gồm 2 tham số: usercurrent_userpost - là đối số thứ hai mà ta muốn authorization. Đối số thứ 2 không nhất thiết luôn luôn là một ActiveRecord, thậm chí là Model Object, nó có thể là bất kỳ thứ gì khác.
  • Các method được implement trong Policy, như cách dùng thứ 2 khi ta khai báo, nó sẽ tự động map với action tương ứng bên phía controller khi được gọi đúng.

Ngoài ra, phía view chúng ta cũng có thể sử dụng policy như sau:

<% if policy(@post).update? %>
  <%= link_to "Edit post", edit_post_path(@post) %>
<% end %>

Phía trên là những điều cơ bản và cách sử dụng đơn giản nhất về gem Pundit.

Bài viết tham khảo tại đây

Thanks for your reading!


All Rights Reserved