我正在尝试学习如何在我的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

我链接的文章和专家文档的主要区别在于,专家自述文件说:
关于类范围,自述文件只有:
类别范围
也就是说,它没有额外的“自述文件在post策略中包含此内容(我的应用程序策略中包含此内容,但也尝试将其添加到建议策略中):
attr_reader:用户,:作用域
自述文件在Post策略中包含此内容(我的应用程序策略中包含此内容,但也尝试将其添加到建议策略中):
def initialize(用户,作用域)
@user=用户
@scope=范围
结束
我试着按照专家文档中的自述文件显示的方式来做——但我得到的错误与我试着跟踪文章时得到的错误相同。
我尝试更改resolve方法,使其始终返回scope.all:
def resolve
       if user.has_role?(:admin)
         scope.all
       else
        scope.all
       end

但我还是犯了同样的错误。
有人知道我需要做什么才能使用专家范围吗?
回顾我今年早些时候的相关问题-我可以看到,无论是在专家创业板上的自述,还是我链接的教程文章似乎都不正确:Rails 4 - Pundit - scoped policy for index
我无法从链接的so帖子中获得任何解决方案,但这些答案中的概念比gem自述文件和教程更彻底。
下一次尝试
专家发现用户的方式有些可疑。
我将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>]>

用户id 43具有名属性Jane我以为这可能是一个信号,表明有些事情正在起作用,但当我改变解决方法,要求“约翰”而不是“简”时,我得到了同样的结果:
(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。
有人知道我需要做什么才能让权威人士认出用户吗?

最佳答案

因此,在对codemontor.io的另一次讨论之后,我没有解决方案,但我已经了解到,我不能将权威范围与政治家的state_machine gem一起使用我要么需要找到另一个授权工具,要么使用不同的状态机器。
我还了解到,专家自述在示例中有几个隐含的假设,使它们不适合使用。
如果我成功地学习了另一个状态机,并再次尝试使用pundit,我将再次发布文章,分享我所学到的关于如何使用pundit作用域的知识。向前。

10-08 00:35