rails4 + Pundit模型实例未在策略中定义

时间:2015-10-09 21:27:46

标签: ruby-on-rails ruby-on-rails-4 pundit

我定义了文档中所述的Pundit策略“CompanyPolicy”,scopez给出了预期的结果(on:index)但是我尝试使用公司模型实例时遇到异常:

 *** NameError Exception: undefined local variable or method `company' for #<CompanyPolicy:

这是CompanyPolicy.rb

  class CompanyPolicy < ApplicationPolicy

      class Scope
        attr_reader :user, :scope

        def initialize(user, scope)
          @user = user
          @scope = scope
        end

        def resolve
          if user.system_admin?
            scope.all
          else
            Company.none
          end
        end
      end

      def new?
        user.system_admin? ? true : false
      end

      def edit?
        user.system_admin? ? true : false
      end

      def show?
        user.system_admin? ? true : false
      end

      def destroy?
        internal_name = Rails.application.secrets.internal_company_short_name
        # do not destroy the internal company record 
        user.system_admin? && (company[:short_name] !=  internal_name ) ? true : false
      end
  end

我从公司控制器检查它

 def destroy
   authorize @company
   #@company.destroy
   ....
 end

为什么(公司[:short_name]错了?

如果我查看Pundit文档,PostPolicy,scope和post.published的示例是类似的......

        class PostPolicy < ApplicationPolicy
          class Scope
            attr_reader :user, :scope

            def initialize(user, scope)
              @user = user
              @scope = scope
            end

            def resolve
              if user.admin?
                scope.all
              else
                scope.where(:published => true)
              end
            end
          end

          def update?
            user.admin? or not post.published?
          end
        end

2 个答案:

答案 0 :(得分:0)

刚刚发现应该使用@record而不是公司 (阅读与范围相关的问题:Implementing scopes in Pundit

但我不明白为什么Pundit doc没有提及它,仍然使用像&#39; post&#39;对于PostPolicy ...... 有人可以启发我们吗?

答案 1 :(得分:0)

查看documentation

  

Pundit对这个类做出如下假设:

     
      
  • 该类与某种模型类具有相同的名称,仅以“Policy”一词为后缀。
  •   
  • 第一个参数是用户。在您的控制器中,Pundit将调用current_user方法来检索要发送到此的内容   论点
  •   
  • 第二个参数是某种模型对象,您要检查其授权。这不需要是一个   ActiveRecord甚至是ActiveModel对象,它可以是任何东西   真。
  •   
  • 该类实现了某种查询方法,在这种情况下更新?通常,这将映射到特定的名称   控制器动作。
  •   
     

真的。

     

通常,您希望继承自创建的应用程序策略   生成器,或设置自己的基类继承自:

class PostPolicy < ApplicationPolicy
  def update?
    user.admin? or not record.published?
  end
end
     

在生成的ApplicationPolicy中,模型对象名为record