Pundit :: NotAuthorizedError-ApplicationPolicy继承无效

时间:2019-03-06 15:56:32

标签: ruby-on-rails ruby inheritance controller pundit

我正在我的应用程序上安装专家。我的RestaurantPolicy文件从ApplicationPolicy继承一个(默认情况下,该文件不提供对任何方法的访问)。当更改RestaurantPolicy中的方法(从false到true)时,它似乎没有任何作用,因为我仍然无法访问任何方法。但是在ApplicationPolicy文件中将false更改为true时...我可以访问!知道为什么RestaurantPolicy文件中的方法不覆盖ApplicationPolicy的方法吗?谢谢你!!

application_controller.rb

dtype

restaurants_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!
  include Pundit

  # Pundit: white-list approach.
  after_action :verify_authorized, except: :index, unless: :skip_pundit?
  after_action :verify_policy_scoped, only: :index, unless: :skip_pundit?

  private

  def skip_pundit?
    devise_controller? || params[:controller] =~ /(^(rails_)?admin)|(^pages$)/
  end
end

restaurant.rb

class RestaurantsController < ApplicationController
  before_action :set_restaurant, only: [:show, :edit, :update, :destroy]

  def index
    @restaurants = Restaurant.all
    authorize @restaurants
  end

  def show
  end

  def new
    @restaurant = Restaurant.new
    authorize @restaurant
  end


  def edit
  end


  def create
    @restaurant = Restaurant.new(restaurant_params)
    @restaurant.user = current_user
# OU :     @restaurant = current_user.restaurants.build(restaurant_params)


    respond_to do |format|
      if @restaurant.save
        format.html { redirect_to @restaurant, notice: 'Restaurant was successfully created.' }
        format.json { render :show, status: :created, location: @restaurant }
      else
        format.html { render :new }
        format.json { render json: @restaurant.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @restaurant.update(restaurant_params)
        format.html { redirect_to @restaurant, notice: 'Restaurant was successfully updated.' }
        format.json { render :show, status: :ok, location: @restaurant }
      else
        format.html { render :edit }
        format.json { render json: @restaurant.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @restaurant.destroy
    respond_to do |format|
      format.html { redirect_to restaurants_url, notice: 'Restaurant was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private

    def set_restaurant
      @restaurant = Restaurant.find(params[:id])
    end

    def restaurant_params
      params.require(:restaurant).permit(:name)
    end
end

user.rb

class Restaurant < ApplicationRecord
  belongs_to :user
end

设计:database_authenticatable,:registerable,          :可恢复,:可记住,:有效   has_many:餐厅 结束

application_policy.rb

class User < ApplicationRecord

restaurant_policy.rb

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end
end

1 个答案:

答案 0 :(得分:1)

您必须在RestaurantPolicy :: Scope之外定义策略方法,就像这样:

class RestaurantPolicy < ApplicationPolicy
  class Scope < Scope
    def index?
      true
    end
  end

  # Notice we have closed the definition of Scope class.
  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    true
  end

  def new?
    create?
  end

  def update?
    true
  end

  def edit?
    update?
  end

  def destroy?
    true
  end
end