嗨!各位朋友大家好,打給後,歹嘎吼,胎尬喉,我是阿圓,一樣有請今天的one piece:
(雷利大叔!!)
鐵人賽的進度來到三分之二了呢!今天想跟各位來介紹 pundit 這個平常在專案裡面,使用程度很高的gem!
若今天的專案比較複雜一點,你可能會需要定義一下 user 權限,除了在controller裡寫下一大堆if...else
判斷外,你有另一個選項是使用pundit 這個 gem。
pundit 會在資料夾中生成與 controller 同名的 policy,而你可以在 policy 去定義跟與各個 action 有關的權限。
首先無例外的記得先到 gemfile :gem "pundit"
(記得bundle)
接著,到 application controller的檔案裡面引入:
class ApplicationController < ActionController::Base
include Pundit
end
最後,記得執行pundit的安裝:rails g pundit:install
這樣,就會長出app/policies/
的這個資料夾,設定好後,就可以在controller、view 裡使用了!
rails g pundit:policy post
就會幫你建立 post 的 policy 了!
policy 設定方法呢,就是定義檢查登入者(user) 有沒有辦法對資料(record) 進行某種操作 (update?),而一般來說,policy 遵從以下幾點:
current_user
這個方法,若沒有使用 devise 這個 gem ,請記得作一個給他!class PostPolicy
attr_reader :user, :post
def initialize(user, post)
@user = user
@post = post
end
def update?
user.admin? or not post.published?
end
end
以上方的例子,我們可以在 post_controller 裡使用authorize
這個方法:
def update
@post = Post.find(params[:id])
authorize @post
if @post.update(post_params)
redirect_to @post
else
render :edit
end
end
就會去執行 post_policy 內的update?
方法。
你也可以在不同的 action 裡,要求與 action 不同名的驗證:
def publish
@post = Post.find(params[:id])
authorize @post, :update?
@post.publish!
redirect_to @post
end
也可以在view裡面呼叫他:
<% if policy(@post).update? %>
<%= link_to "Edit post", edit_post_path(@post) %>
<% end %>
以上是比較基本的用法!
如果想某些 user 來做驗證,可以使用scope:
class PostPolicy < ApplicationPolicy
class Scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin?
scope.all
else
scope.where(published: true)
end
end
private
attr_reader :user, :scope
end
def update?
user.admin? or not record.published?
end
end
特別要說的是,pundit 也能處理 params:
# in policy
class PostPolicy < ApplicationPolicy
def permitted_attributes
if user.admin? || user.owner_of?(post)
[:title, :body, :tag_list]
else
[:tag_list]
end
end
end
# in controller
def update
@post = Post.find(params[:id])
if @post.update_attributes(permitted_attributes(@post))
redirect_to @post
else
render :edit
end
end
也可以針對不同action,有不同的permitted_attributes
class PostPolicy < ApplicationPolicy
def permitted_attributes_for_create
[:title, :body]
end
def permitted_attributes_for_edit
[:body]
end
end
以上就是有關 pundit 的基本介紹啦!感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見!