在我的应用程序中,我有Permission表,它存储用户可以执行的所有逻辑。 使用Pundit我想允许用户在权限表允许的情况下创建新的广告系列。如果权限表包含此信息,用户可以访问广告系列并创建新广告:
到目前为止,我一直收到错误" Pundit :: NotDefinedError",无法找到nil的策略策略/ application_policy.rb是标准的,没有变化。 显然我做错了。如何正确执行此授权?非常感谢您的帮助!我在Rails 5 + Pundit上。
模型/ permission.rb
class Permission < ApplicationRecord
belongs_to :permitable, polymorphic: true
belongs_to :user
enum level: {owner: 1, view: 2, edit: 3}
end
模型/ user.rb
has_many :permissions
has_many :campaigns, through: :permissions, source: :permitable, source_type: 'Campaign' do
def owner_of
where('`permissions`.`level` & ? > 0', Permission::owner )
end
end
has_many :sysmodules, through: :permissions, source: :permitable, source_type: 'Sysmodule' do
def can_access
where('`permissions`.`level` & ? > 1', Permission::can_access )
end
end
控制器/ campaigns_controller.rb
def new
@campaign = Campaign.new
authorize @campaign
end
政策/ campaign_policy.rb
class CampaignPolicy < ApplicationPolicy
attr_reader :user, :campaign, :permission
@user = user
@permission = permission
end
def new?
user.permission? ({level: 3, permitable_type: "Sysmodule", permitable_id: 2})
end
视图/活动/ index.html.erb
<% if policy(@campaign).new? %>
</li>
<li><%= link_to "New campaign", new_campaign_path(@campaign) %></li>
</li>
<% end %>
答案 0 :(得分:0)
不要直接处理用户应该拥有的权限,而应该考虑用户在系统中可以拥有的角色。
这使得创建映射到现实世界问题的授权规则变得更加容易。
让我们想象一下我们拥有用户和组的示例。规则如下:
模特:
class User < ApplicationRecord
rolify
end
class Group < ApplicationRecord
resourcify
end
政策:
class GroupsPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.with_roles([:admin, :member], current_user)
end
end
def show?
user.has_role?([:member, :admin], record)
end
def index?
true
end
def create?
true # any user can create
end
def new?
create?
end
def update?
user.has_role?(:admin, record)
end
def edit?
update?
end
def destroy?
update?
end
end
控制器
class GroupsController < ApplicationController
respond_to :html
before_action :autenticate!
before_action :set_group!, only: [:show, :edit, :update, :destroy]
def show
respond_with(@group)
end
def index
@groups = policy_scope(Group.all)
respond_with(@groups)
end
def new
@group = authorize( Group.new )
end
def create
@group = authorize( Group.new(group_attributes) )
if @group.save
current_user.add_role(:member, @group)
current_user.add_role(:admin, @group)
end
respond_with(@group)
end
def edit
end
def update
@group.update(group_params)
respond_with(@group)
end
def destroy
@group.destroy
respond_with(@group)
end
private
def set_group!
@group = authorize( Group.find(params[:id]) )
end
def group_params
params.require(:group).permit(:name)
end
end