【发布时间】:2016-09-25 16:14:07
【问题描述】:
在我的应用程序中,我有权限表,其中存储了用户可以执行的所有逻辑。 如果权限表允许,我希望通过 Pundit 允许用户创建新的活动。如果权限表包含此信息,用户可以访问活动并创建新的:
- permitable_type: Sysmodule // 我存储系统部分信息的另一个表,其中 Campaigns 是其中之一
- permitable_id: 2 // 表示来自 Sysmodule 的活动
- 级别:3 // 表示用户可以在广告系列部分编辑内容
到目前为止,我一直收到错误“Pundit::NotDefinedError”,无法找到 nil 的策略,policies/application_policy.rb 是标准的,没有变化。 显然我做错了什么。如何正确进行此授权?非常感谢您的帮助!我在 Rails 5 + Pundit 上。
models/permission.rb
class Permission < ApplicationRecord
belongs_to :permitable, polymorphic: true
belongs_to :user
enum level: {owner: 1, view: 2, edit: 3}
end
models/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 %>
【问题讨论】:
-
通过
permissions表上的多态关系加入所有内容将是一个巨大的性能问题。虽然::(Permission::owner) 在 Ruby 中不是很好的风格,但也调用类方法,因为它看起来像是在访问模块常量。 -
我认为你想要做的是
Permission.levels[:owner]。Permission::owner实际上等于Permission.where(level: :owner) -
@max 对于能够为任何用户设置任何对象(例如广告系列)的权限(查看/编辑/删除),您有什么建议?假设,从数据库中的 10 个活动中,用户可以查看两个,编辑两个,是两个的所有者,但不能访问四个。
-
基于角色的基本访问系统可能是更好的选择。 github.com/RolifyCommunity/rolify
标签: ruby-on-rails permissions pundit