rails_admin_pundit icon indicating copy to clipboard operation
rails_admin_pundit copied to clipboard

NoMethodError at / undefined method `policy' for #<RailsAdmin::MainController:0x0055914e2523a0>

Open btazi opened this issue 8 years ago • 3 comments

I honestly don't know if this is a bug or an issue with my implementation, but I followed all the instructions and still can't figure out a solution. I'm on Rails 5 and I use pundit with devise. rails_admin_pundit_bug_full

Here's a snippet of my Gemfile:

gem 'devise'
gem 'devise-i18n'
gem 'rails_admin', '~> 1.0'
gem 'rails_admin-i18n'
gem 'rails_admin_tag_list', github: 'kryzhovnik/rails_admin_tag_list'
gem 'pundit'
gem "rails_admin_pundit", :github => "sudosu/rails_admin_pundit"

And a snippet of my rails_admin initializer:

RailsAdmin.config do |config|
  config.authorize_with :pundit
  config.current_user_method(&:current_user)
  ...
end

My Application policy looks like this:

class ApplicationPolicy
  attr_reader :current_user, :record

  def initialize(current_user, record)
    @user = current_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 rails_admin?(action)
        case action
        when :dashboard
            @user.admin?
        when :index
            @user.admin?
        when :show
            @user.admin?
        when :new
            @user.admin?
        when :edit
            @user.admin?
        when :destroy
            @user.admin?
        when :export
            @user.admin?
        when :history
            @user.admin?
        when :show_in_app
            @user.admin?
        else
            raise ::Pundit::NotDefinedError, "unable to find policy #{action} for #{record}."
        end
    end

end

Do you have any idea why this isn't working ? Thanks in advance

ps: I created a question on stackoverflow

btazi avatar Nov 02 '16 10:11 btazi

I ran into this today. The problem is that rails_admin 1.0.0 introduced its own :pundit authorization policy, which supercedes the rails_admin_pundit policy.

In order to work around this on my own project, I have done the following:

  • Removed the rails_admin_pundit gem
  • Updated the rails_admin gem to 1.2.0
  • Added the following initializer in order to still use the rails_admin? policy within the ApplicationPolicy (because I want to have my rails_admin policies separate from my other ones).
RailsAdmin.config do |config|
  config.current_user_method { current_user } # auto-generated

  config.authorize_with :pundit
end

module RailsAdmin
  module Extensions
    module Pundit
      class AuthorizationAdapter
        def authorize(action, abstract_model = nil, model_object = nil)
          record = model_object || abstract_model && abstract_model.model
          if action && !policy(record).send(*action_for_pundit(action))
            raise ::Pundit::NotAuthorizedError.new("not allowed to #{action} this #{record}")
          end
          @controller.instance_variable_set(:@_pundit_policy_authorized, true)
        end

        def authorized?(action, abstract_model = nil, model_object = nil)
          record = model_object || abstract_model && abstract_model.model
          policy(record).send(*action_for_pundit(action)) if action
        end

        def action_for_pundit(action)
          [:rails_admin?, action]
        end
      end
    end
  end
end

rdunlop avatar Sep 10 '17 17:09 rdunlop

@rdunlop Thank your solution, but a little problem in there:

when i update any file (just add a space) will catch an error NoMethodError in RailsAdmin::MainController#dashboard undefined method 'policy' for ....

However, restarted rails server everything is ok.

Is this problem's reason: all initializers script only run once at rails server startup ?

beitaz avatar Apr 18 '18 03:04 beitaz

@beitaz I finally got around to upgrading my project...and I think I may have resolved your issue.

in initializers/rails_admin.rb

RailsAdmin.config do |config|
  # This is necessary in order to avoid issues when in development
  # The way that RailsAdmin patches in the "include Pundit" is not
  # working well with  the auto-reloading, and so, we specify
  # a controller which explicitly already does "include Pundit"
  config.parent_controller = "ApplicationController"

rdunlop avatar Sep 27 '18 13:09 rdunlop