Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecation warnings about initializer autoloading constants in Rails 6 #3190

Closed
sedubois opened this issue Sep 4, 2019 · 9 comments
Closed

Comments

@sedubois
Copy link
Contributor

sedubois commented Sep 4, 2019

I have a Rails 5.2 app with RailsAdmin 2.0. When updating to Rails 6 with classic autoloader (not yet Zeitwerk) I get these warnings:

DEPRECATION WARNING: Initialization autoloaded the constants PaperTrail::Version, RailsAdmin::ApplicationHelper, RailsAdmin::MainHelper, RailsAdmin::ApplicationController, RailsAdmin::ModelNotFound, RailsAdmin::ObjectNotFound, RailsAdmin::ActionNotAllowed, ActionText::ContentHelper, and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload PaperTrail::Version, for example,
the expected changes won't be reflected in that stale Class object.

`config.autoloader` is set to `classic`. These autoloaded constants would have been unloaded if `config.autoloader` had been set to `:zeitwerk`.

Please, check the "Autoloading and Reloading Constants" guide for solutions.

My initializers/rails_admin.rb looks like this:

RailsAdmin.config do |config|

  ### Popular gems integration

  ## == Devise ==
  config.authenticate_with do
    warden.authenticate! scope: :administrator
  end
  config.current_user_method(&:current_administrator)
  RailsAdmin::ApplicationController.class_eval do
    def user_for_paper_trail
      return unless administrator_signed_in?
      "Administrator ##{current_administrator.id}"
    end
  end

  ## == PaperTrail ==
  config.audit_with :paper_trail, 'Administrator', 'PaperTrail::Version' # PaperTrail >= 3.0.0

  config.actions do
    dashboard
    index
    new
    export
    show
    edit
    delete
    show_in_app
    move_lower
    move_higher
    move_to_bottom
    move_to_top

    audit_models = %w(Subscription Testimonial ThoughtOfTheDay)
    config.actions do
      history_index do
        only audit_models
      end
      history_show do
        only audit_models
      end
    end
  end

  config.parent_controller = "Admin::BaseController"
  
  ...
end

From what I understood the documentation basically says that constants should simply not be autoloaded in initializers:
https://guides.rubyonrails.org/autoloading_and_reloading_constants_classic_mode.html#autoloading-and-initializers

My understanding is that things would not work at all if I instead used Zeitwerk, which is the new default autoloader.

How should RailsAdmin be configured if constants cannot be autoloaded in the initializer any more?

@emmanuelperotto
Copy link

Same warnings here... did you find any solution?

@sedubois
Copy link
Contributor Author

sedubois commented Sep 8, 2019

Not so far.

(RailsAdmin also seems to no longer work with the Pundit integration so I might need to move to another library altogether (getting errors Post(id: integer, ...) is not an ActiveRecord::Relation).)

@tinbka
Copy link

tinbka commented Sep 19, 2019

Having debugging this quite a bit, I found out that all of those were autoloaded by the audit_with instruction.

Personally, I've disabled it because it's not critical for my project.

Hope it helps to fix the deprecation warning.

@tinbka
Copy link

tinbka commented Sep 19, 2019

Another issue related to Rails 6 autoloading is that if I define in lib/rails_admin/config/actions/do_something.rb

class RailsAdmin::Config::Actions::DoSomething < RailsAdmin::Config::Actions::Base
...
end

Then register it in config/initializers/rails_admin.rb with

RailsAdmin::Config::Actions.register(:do_something, 'RailsAdmin::Config::Actions::DoSomething')

In Rails 5.2 it would load just fine. I'm not sure if it's auto-reloaded well though.

But Rails 6 will complain on boot

DEPRECATION WARNING: Initialization autoloaded the constant RailsAdmin::Config::Actions::DoSomething.

That's because in do_something in config.actions block triggers #add_action_custom_key defined in rails_admin-2.0.0/lib/rails_admin/config/actions.rb, which eventually evaluates the class name triggering the "deprecated way of autoloading".

I'm not sure why RailsAdmin does that, but weren't it constantize action classes on initialization, they would've been auto-reloadable!

Currently, the solution to get rid of the deprecation warning regarding the action classes is to require their definition files literally in config/initializers/rails_admin.rb.

@ArturT
Copy link

ArturT commented Sep 21, 2019

I'm using rails_admin 2.0.0 and rails 6.0.0. I get the same warning as @tinbka in above comment.

Without doing require for custom action files above config/initializers/rails_admin.rb you can't use custom action. Route returns 404.

Doing require for custom action file triggers deprecation warning.

@fuegas
Copy link
Contributor

fuegas commented Oct 18, 2019

I've run into this as well. After some searching it narrowed down to these lines in lib/rails_admin/extensions/paper_trail/auditing_adapter.rb at line 55 in def self.setup:

RailsAdmin::ApplicationController.class_eval do
  def user_for_paper_trail
    _current_user.try(:id) || _current_user
  end
end

Evaluating these lines causes the warnings to be shown.

I was not sure how @tinbka solved it so I'll add my workaround. The following works for Rails 6.0 in API only mode:

app/controllers/application_admin_controller.rb:

# frozen_string_literal: true

# Dedicated application controller for RailsAdmin
class ApplicationAdminController < ActionController::Base
  # Tell RailsAdmin which user changed something
  def user_for_paper_trail
    _current_user.try(:id) || _current_user
  end
end

config/initializers/rails_admin.rb:

# frozen_string_literal: true

# Monkey patch AuditingAdapter to prevent setup loading classes in initializer
# See: https://github.com/sferik/rails_admin/issues/3190
class RailsAdmin::Extensions::PaperTrail::AuditingAdapter
  def self.setup; end
end

# Rails admin configuration
RailsAdmin.config do |config|
  # Which class should be used for the controllers
  config.parent_controller = '::ApplicationAdminController'

  ## == PaperTrail ==
  config.audit_with :paper_trail, 'User', 'PaperTrail::Version'

  # Other config as usual from here
end

@ziaulrehman40
Copy link

I am seeing these warnings only when i run rspec after installing rails admin v2.0.0

@mshibuya
Copy link
Member

e275012 should have fixed this.

@sedubois
I don't see any issue with pundit integration, please open another issue if you still have the problem.

@tinbka
Reloading action is not supported because they are kept in actions registry.
For now, I recommend not to autoload by explicitly requiring:

require 'rails_admin/config/actions/do_something'
RailsAdmin::Config::Actions.register(:do_something, 'RailsAdmin::Config::Actions::DoSomething')

@batdevis
Copy link

the problem persists following the indications of the wiki about creating a reusable action.

I resolved copying in the initializer the content of register method of actions.rb, like this:

klass = CustomAdmin::AddNextSlot
name = klass.to_s.demodulize.underscore.to_sym
    RailsAdmin::Config::Actions.instance_eval %{
      def #{name}(&block)
        action = #{klass}.new
        add_action_custom_key(action, &block)
      end
    }

instead of

RailsAdmin::Config::Actions.register(CustomAdmin::AddNextSlot)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants