Pundit::NotAuthorizedError - ApplicationPolicy 继承不起作用
Pundit::NotAuthorizedError - ApplicationPolicy inheritance doesn't work
我正在我的应用程序上安装 pundit。我的 RestaurantPolicy 文件继承自 ApplicationPolicy 文件(默认情况下允许访问 none 方法)。当更改 RestaurantPolicy 中的方法(从 false 到 true)时,它似乎没有任何效果,因为我仍然可以访问 none 的方法。但是在 ApplicationPolicy 文件中将 falses 更改为 trues 时......我有访问权限!知道为什么 RestaurantPolicy 文件中的方法没有覆盖 ApplicationPolicy 的方法吗?谢谢你!!
application_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
restaurants_controller.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
restaurant.rb
class Restaurant < ApplicationRecord
belongs_to :user
end
user.rb
class User < ApplicationRecord
设计:database_authenticatable,:可注册,
:可恢复,:可记忆,:可验证
has_many:餐厅
结束
application_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
restaurant_policy.rb
class RestaurantPolicy < ApplicationPolicy
class Scope < Scope
def index?
true
end
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
end
您必须从 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
我正在我的应用程序上安装 pundit。我的 RestaurantPolicy 文件继承自 ApplicationPolicy 文件(默认情况下允许访问 none 方法)。当更改 RestaurantPolicy 中的方法(从 false 到 true)时,它似乎没有任何效果,因为我仍然可以访问 none 的方法。但是在 ApplicationPolicy 文件中将 falses 更改为 trues 时......我有访问权限!知道为什么 RestaurantPolicy 文件中的方法没有覆盖 ApplicationPolicy 的方法吗?谢谢你!!
application_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
restaurants_controller.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
restaurant.rb
class Restaurant < ApplicationRecord
belongs_to :user
end
user.rb
class User < ApplicationRecord
设计:database_authenticatable,:可注册, :可恢复,:可记忆,:可验证 has_many:餐厅 结束
application_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
restaurant_policy.rb
class RestaurantPolicy < ApplicationPolicy
class Scope < Scope
def index?
true
end
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
end
您必须从 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