0
我使用pundit gem
爲了授予三個不同用戶(Admin,seller,viewer)的權限。目前我得到了一切工作,管理員可以訪問所有內容,賣家可以查看他們自己的產品,查看器可以查看產品。Rails pundit gem,允許查看非登錄用戶
我遇到的唯一問題是我希望非signed_up/signed_in用戶能夠通過搜索結果查看產品。現在,非sign_up/signed_in用戶可以看到搜索結果,但無法訪問節目視圖。
這裏是設置我有:
class ItemPolicy < ApplicationPolicy
attr_reader :item
def initialize(user, record)
super(user, record)
@user = user
@item = record
end
def update?
@user.is_a?(Admin) ? item.all : @user.items
end
def index?
@user.is_a?(Admin) ? item.all : @user.items
end
def show?
@user.is_a?(Admin) ? item.all : @user.items
end
def create?
@user.is_a?(Admin) ? item.all : @user.items
end
def new?
@user.is_a?(Admin) ? item.all : @user.items
end
def edit?
@user.is_a?(Admin) ? item.all : @user.items
end
def destroy?
@user.is_a?(Admin) ? item.all : @user.items
end
class Scope < Struct.new(:user, :scope)
def resolve
if user.is_a?(Admin)
scope.where(:parent_id => nil)
elsif user.is_a?(Seller)
scope.where(:id => user.items)
end
end
def show?
return true if user.is_a?(Admin)
return true if user.seller_id == seller.id && user.is_a?(Seller)
false
end
end
end
控制器:
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
def index
authorize Item
@items = policy_scope(Item)
end
def search
if params[:term]
@items = Item.search(params[:term]).order("created_at DESC")
else
@items = []
end
end
def show
@comments = Comment.where(item_id: @item).order("created_at DESC")
@items = policy_scope(Item).find(params[:id])
authorize @item
end
def new
@item = Item.new
authorize @item
@categories = Category.order(:name)
end
def edit
authorize @item
@categories = Category.order(:name)
end
def create
@item = Item.new(item_params)
authorize @item
respond_to do |format|
if @item.save
format.html { redirect_to @item, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
def update
authorize @item
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
def destroy
authorize @item
@item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: 'Item was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_item
@item = Item.find(params[:id])
authorize @item
end
def item_params
params.require(:item).permit(:title, :description, :image, :price, :category_id)
end
end
application_contoller.rb
class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery prepend: true
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
def pundit_user
current_seller || current_admin || current_viewer
end
private
def user_not_authorized(exception)
policy_name = exception.policy.class.to_s.underscore
flash[:warning] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
redirect_to(request.referrer || root_path)
end
end
更新1
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
raise Pundit::NotAuthorizedError, "must be logged in" unless user
@user = user
@record = record
end
def index?
true # anybody can view
end
def show?
true # anybody can view
end
def search?
index?
end
def new?
create?
end
def edit?
update?
end
def destroy?
update?
end
private
# don't repeat yourself
def admin?
user.is_a?(Admin)
end
def seller?
user.is_a?(Seller)
end
end
class ItemPolicy < ApplicationPolicy
attr_reader :item
class Scope < Struct.new(:user, :scope)
def resolve
if admin?
scope.where(parent_id: nil)
elsif seller?
# avoids a query for user.items
scope.where(seller: user)
end
end
end
def initialize(user, record)
super(user, record)
@user = user
@item = record
end
def update?
admin? || is_owner?
end
def create?
# just guessing here
admin? || seller?
end
private
def is_owner?
# or whatever the association between the item and its owner is
item.seller == user
end
end
感謝您的信息和幫助再次@最大!我根據你的回答更新了我的代碼,但仍然無法讓'非授權用戶'查看展示頁面......當用戶登錄時,他現在可以查看和編輯所有項目。我已經添加了更新1到我的問題,所以你可以看到我迄今爲止做了什麼。 – Theopap
管理員可以查看和編輯所有項目。如果那不是你想要的更改#update中的邏輯?方法。此外,爲了讓無理由的用戶訪問資源,您需要跳過Devise'authorize_user!' (或者不管它是什麼)回調。 – max
是的,這正是我想要的,管理員有權訪問所有項目,賣家只有他的項目,查看者只有搜索結果索引和顯示....但目前與您的更改...已登錄的賣家可以編輯/查看/刪除所有項目。 – Theopap