Pundit无法找到命名空间策略

时间:2014-12-30 19:47:25

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

我已经阅读了同一主题的几个问题,但没有一个能解决我的怀疑或为我工作。

Pundit无法在我的代码中找到命名空间策略,但我无法理解原因。我有一个'后端'命名空间,只要调用此后端中的 items_controller.rb ,就会使用 app / policies / item_policy.rb ,而不是 app / policies / backend / item_policit.rb

请非常感谢任何帮助。我花了很多时间在这个问题上。

我的 app / policies / 目录:

application_policy.rb
backend_policy.rb
item_policy.rb
backend/item_policy.rb

application_policy.rb

class ApplicationPolicy
  attr_reader :user, :record

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

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

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

    def resolve
      scope
    end
  end
end

backend_policy.rb

class Backend::ApplicationPolicy < ApplicationPolicy
  attr_reader :user, :record

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

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

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

    def resolve
      scope
    end
  end
end

后端/ item_policy.rb

class Backend::ItemPolicy < Backend::ApplicationPolicy
  attr_reader :user, :item

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

  def index?
    raise Pundit::NotAuthorizedError, "must be logged in" unless @user.admin?
  end
end

控制器/后端/ items_controller.rb

class Backend::ItemsController < Backend::ApplicationController
  before_action :set_item, only: [:show, :edit, :update, :destroy]
  after_action :verify_authorized

  # GET /backend/items
  # GET /backend/items.json
  def index
    @search = Item.search (search_params)
    @items = @search.result().page(params[:page]).per(12)
    authorize Item
  end
....
end

1 个答案:

答案 0 :(得分:2)

这是您在pundit code

中提取政策名称的方式
def find
  if object.respond_to?(:policy_class)
    object.policy_class
  elsif object.class.respond_to?(:policy_class)
    object.class.policy_class
  else
    klass = if object.respond_to?(:model_name)
      object.model_name
    elsif object.class.respond_to?(:model_name)
      object.class.model_name
    elsif object.is_a?(Class)
      object
    elsif object.is_a?(Symbol)
      object.to_s.classify
    else
      object.class
    end
    "#{klass}Policy"
  end
end

因此,要么为模型添加函数“policy_class”,要么为模型本身添加名称空间