我正在尝试学习如何在我的Rails 5应用程序中使用pundit。
我试图按照本文中的方法进行操作。
https://learn.co/lessons/devise_pundit_readme
我正在努力通过这种方法找到工作结果。具体来说,我尝试使用定义范围的索引中的行是:
<% policy_scope(@user.proposals).each do |prop| %>
正在返回此错误:
undefined method `proposals' for nil:NilClass
我的设置是:
我有用户和提案的模型。协会是:
用户:
has_many :proposals
提案:
belongs_to :user
应用程序控制器:
include Pundit
建议控制人:
def index
@proposals = Proposal.all
# @bips = @proposal.bips
authorize @proposals
end
提案政策:
class ProposalPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.has_role?(:admin)
scope.all
else
scope.where(:current_state == :draft)
end
end
end
def index?
true
end
提案索引:
<% policy_scope(@user.proposals).each do |prop| %>
<%= prop.title %>
<%= prop.user.full_name %>
<%= prop.created_at %>
<%= link_to 'More', proposal_path(prop) %>
<% end %>
当我尝试这个时,我收到一个错误 - 突出显示我索引的这一行的问题:
<% policy_scope(@user.proposals).each do |prop| %>
鉴于这与我链接的文章完全相同,我失去了为什么它不起作用。
错误说:
undefined method `proposals' for nil:NilClass
我链接的文章和Pundit文档之间的主要区别在于Pundit自述文件说:
关于课程范围 - 自述文件只有:
班级范围
即。它没有额外的&#34;&lt;范围&#34;
自述文件在邮政政策中有这个(我在我的申请政策中有这个 - 但是也尝试将其添加到投标政策中):
attr_reader:user,:scope
自述文件在邮政政策中有这个(我在我的申请政策中有这个 - 但是也尝试将其添加到投标政策中):
def初始化(用户,范围) @user = user @scope =范围 端
我尝试按照专家文档中的自述文件的方式进行操作 - 但是当我尝试阅读文章时,我得到了同样的错误。
我尝试更改resolve方法,以便始终返回scope.all:
def resolve
if user.has_role?(:admin)
scope.all
else
scope.all
end
但我仍然得到同样的错误。
任何人都可以看到我需要做什么才能使用Pundit范围?
回顾今年早些时候的相关问题 - 我可以看到,关于专家宝石的自述文件和我链接的教程文章似乎都不正确:Rails 4 - Pundit - scoped policy for index
我无法从链接的SO帖子中获得任何解决方案 - 但这些答案中的概念比gem自述文件和教程更全面。
下次尝试
pundit找到用户的方式有点可疑。
我将resolve方法更改为非常简单的方法 - 检查用户的名字值是否等于字符串(这是我的用户表的记录,该用户表是我登录的用户名的第一个名称):
class ProposalPolicy < ApplicationPolicy
class Scope #< Scope
# class Scope
attr_reader :user, :scope
def initialize(user, scope)
user = user
scope = scope
end
def resolve
if user.first_name == "Jane"
scope.all
else
scope.where(:current_state == :draft)
end
end
end
当我尝试这个时,我收到的错误是:
undefined method `first_name' for nil:NilClass
我不认为专家知道如何找到用户。
当我在我的提案索引操作中添加一个byebug时,我得到:
user.inspect
*** NameError Exception: undefined local variable or method `user' for #<ProposalsController:0x007fa3e8cf8698>
(byebug) @user
nil
(byebug) current_user
#<User id: 43, first_name: "Jane",
所以 - 我试图让权威人士认识用户的方式出了问题。我已经在GitHub上搜索了数百个回购,试图找到人们如何使用它的例子。我无法找到与我在链接帖子中尝试的所有选项不同的内容。
我不确定它是否奇怪,但我能做到:
(byebug) policy_scope(Proposal)
Proposal Load (0.4ms) SELECT "proposals".* FROM "proposals"
#<ActiveRecord::Relation [#<Proposal id: 17, user_id: 43, title: "asdf", description: "adsf", byline: "asdf", nda_required: true, created_at: "2016-11-16 00:28:31", updated_at: "2016-11-28 01:16:47", trl_id: 1>]>
user_id 43具有Jane的first_name属性。我认为这可能是某些事情有效的迹象,但是当我改变解决方法来要求&#34; John&#34;而不是&#34; Jane&#34;,我得到了相同的结果:
(byebug) policy_scope(Proposal)
Proposal Load (0.8ms) SELECT "proposals".* FROM "proposals"
#<ActiveRecord::Relation [#<Proposal id: 17, user_id: 43, title: "asdf", description: "adsf", byline: "asdf", nda_required: true, created_at: "2016-11-16 00:28:31", updated_at: "2016-11-28 01:16:47", trl_id: 1>]>
显然,这次它不正确,因为此提案所属的用户的名字不是John。
任何人都可以看到我需要做些什么来让Pundit识别用户吗?
答案 0 :(得分:0)
所以,在关于codementor.io的另一场会议之后,我没有解决方案,但我了解到我不能将Pundit范围与政治家state_machine gem一起使用。我要么找到另一个授权工具,要么使用不同的状态机工具。
我还了解到,专家自述文件在示例中有几个隐含的假设,使它们不适合使用。
如果我设法学习另一台状态机并再次与Pundit一起尝试,我将再次发布以分享我所学到的关于如何使用权威范围的知识。起。