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

ArgumentError: A copy of ApplicationController has been removed from the module tree but is still active #2334

Closed
subhashb opened this issue Jul 10, 2013 · 60 comments

Comments

@subhashb
Copy link

I am using the latest master, with Rails: 4.0.0.rc2
I experience the above exception, only when I change something in admin/*.rb files, and try to refresh the view.

The entire gist of the problem is here: Stackoverflow 17561697

I think this is related to ActiveAdmin + InheritedResources generated controllers "not being" in the autoload path of Rails, but I might be wrong.

Not sure if this is related to #697 either.

Is there a way to circumvent the problem?

@seanlinsley
Copy link
Contributor

@subhashb
Copy link
Author

I think unloadable has been deprecated.
The solution may lie in making Controllers generated by inherited_resources autoloadable.

When I check the list of Autoloaded constants in dependencies.rb, the array does not have activeadmin generated controllers in it. Could this be the problem?

By default, all directories under app are in the autoload path. Not sure if I should add something explicitly to mark these controllers as autoload, or how to go about doing it.

@seanlinsley
Copy link
Contributor

Does this occur if you create a brand new app on Rails 4 with AA?

@subhashb
Copy link
Author

Yep. You can check this project to simulate the problem: https://github.com/highnotes/eardrums

Start up rails and guard, and change something in the app/admin/* files. You should start getting the above exception after that.

@seanlinsley
Copy link
Contributor

Thanks for the project; I'll try and look into this today.

@stereoscott
Copy link
Contributor

I'm getting hit with this too. Rails 4.0.0 and the rails4 branch of active admin. I realize this comment doesn't help much, but so far my hunches indicate it has something to do with having devise on both a frontend and a backend with different user models.. before I started using devise on the frontend for authentication, I never ran into this issue.

#Gemfile.lock
remote: git://github.com/gregbell/active_admin.git
  revision: 72a9c30cef47b3f38c38039de021aaa3194c188b
  branch: rails4

@seanlinsley
Copy link
Contributor

@stereoscott can you provide more details?

@subhashb I'm not sure exactly why this is happening, but I found a workaound. Change this:

def current_permission
  @current_permission ||= Permissions.permission_for(current_user)
end

To this:

def current_permission
  @current_permission ||= ::Permissions.permission_for(current_user)
end

The error is raised at this point in ActiveSupport:

# Load the constant named +const_name+ which is missing from +from_mod+. If
# it is not possible to load the constant into from_mod, try its parent
# module using +const_missing+.
def load_missing_constant(from_mod, const_name)
  log_call from_mod, const_name

  unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
    raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
  end
  # ...

The problem only occurs when you don't fully qualify the constant name, so Rails tries looking it up in the ApplicationController namespace.

@subhashb
Copy link
Author

Yep, that solved the problem! And you are right, seems to be a problem with looking up the constant under a different namespace.

@seanlinsley
Copy link
Contributor

Cool. Could you mark your SO question as answered?

@subhashb
Copy link
Author

Marked as answered and Accepted! Muchas Gracias!

@derekprior
Copy link

This doesn't seem closed to me. I also see this and am able to work around it by adding the absolute namespace qualification somewhat randomly to things in my application controller. Trouble is that's not very self-documenting and there seemingly isn't much rhyme or reason to where its needed.

@seanlinsley
Copy link
Contributor

Unfortunately you're right @derekprior. This is likely to be the cause: #2329 (comment). I've been quite busy lately so haven't revisited that. Hopefully I'll get to it soon.

If you want, you could try ensuring that app/admin isn't in your eager_load_paths. If it is currently, and the problem goes away when you remove it, then the solution is clear.

@davidyang
Copy link

Hi Daxter - what's the recommended way to prevent ActiveAdmin from adding itself to the load path?

@seanlinsley
Copy link
Contributor

Do you mean in reference to my comment yesterday? And just to clarify, AA doesn't add itself to the load path, Rails does it automatically for any folder inside of the app directory.

@davidyang
Copy link

I've got an app where I've got some classes in app/models (not ActiveRecord) like sidenav.rb (class Sidenav; end)

If I don't put ::Sidenav in ApplicationController, every now and then I'll get this error ("A copy of ApplicationController has been removed from the module tree but is still active"). It appears that it's related to this but I'm not quite sure how.

Should I reject!( app/admin ) from the eager_load_path in the config?

@seanlinsley
Copy link
Contributor

@davidyang can you try out #2484?

@thehappycoder
Copy link

Still got it with rails 4.0.1 and activeadmin (master branch). It happens all the time for me.

@seanlinsley
Copy link
Contributor

@thehappycoder can you try isolating the problem code so we have something to work from?

@thehappycoder
Copy link

To reproduce I just had to:

  1. Load rails app
  2. Log in as admin (devise) or be already logged in
  3. Load active admin page
  4. Change DSL for that page
  5. Reload page
  6. Get ArgumentError: A copy of ApplicationController has been removed from the module tree but is still active inside "load_common" method, first line

It started to work fine when I commented the before_action

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_action :authenticate_user!
  #before_action :load_common

  after_action :disable_cache_for_xhr

  helper_method :ip_banned?

  protected

  def authenticate_admin_user!
    redirect_to(new_user_session_path) unless current_user.try(:admin?)
  end

  def load_common
    @common_presenter = CommonPresenter.new
  end

  def ip_banned?(request)
    BannedContact.ip_banned?(request.remote_ip)
  end

  def cities_settings(request)
    cities_settings_json = request.cookies['cities_settings']

    if cities_settings_json
      JSON.parse(cities_settings_json)
    else
      {}
    end
  end

  def disable_cache_for_xhr
    if request.xhr?
      response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
      response.headers["Pragma"] = "no-cache"
      response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
    end

    true
  end
end

If it happens again, I will let you know.

@subhashb
Copy link
Author

subhashb commented Nov 2, 2013

@thehappycoder Can you try fully qualifying the constant name, like so ::CommonPresenter.new in load_common?

@thehappycoder
Copy link

::CommonPresenter.new solves the problem

@subhashb
Copy link
Author

subhashb commented Nov 2, 2013

Yeah, that's the workaround I found too. Otherwise, AA seems to be trying to lookup the constant in a different namespace.

@jaredbrown
Copy link

I have the following method in application_controller.rb

def current_user
  if Rails.env.test?
    @current_user ||= ::User.find(session[:user_id]) if session[:user_id]
  else
    @current_user ||= ::User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token]
  end
end

But I get the following error:

ArgumentError in Admin::DashboardController#index
A copy of ApplicationController has been removed from the module tree but is still active!

On line: @current_user ||= ::User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token]

This is with the 1.0.0-pre gem.

@Ricardonacif
Copy link

I'm getting this error now. I need to restart the rails server in order to work every time I change something in a file inside app/admin

@seanlinsley
Copy link
Contributor

@Ricardonacif can you post a stack trace?

@ChristianPeters
Copy link

fully qualifying the constant name, like so ::CommonPresenter.new

Thanks @subhashb for the workaround. Would be great to have this fixed – we restarted the server hundreds of times before starting looking for this. x)

@jayshepherd
Copy link
Contributor

We also had this problem and fully qualifying our objects in the ApplicationController was the trick.

So, to be clear, I looked for any of our specific models and preceded with ::

Example:
A reference to UserSession was updated to ::UserSession

@westonplatter
Copy link

Fully qualifying all constants solved the issue for: Rails 4.1.15 // ActiveAdmin 1.0.0.pre2

Example:
A reference to UserSession was updated to ::UserSession

@mklnz
Copy link

mklnz commented Sep 23, 2016

I'm still getting the circular dependency issue with Rails 4.2.7 and latest ActiveAdmin from git
After doing a fresh install, the generator adds app/admin/admin_user.rb, but seems to conflict with app/models/admin_user.rb

Coming from an older version I recall all models were plural, but now it seems they are singular?

What's interesting is this issue only exists when requiring the Rails environment from an external script, e.g. require_relative 'config/environment' and does not show up when running standard rails s

RuntimeError: Circular dependency detected while autoloading constant AdminUser
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:492:in `load_missing_constant'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:184:in `const_missing'
    from /Users/michael/Development/pingzapper-site/app/admin/admin_user.rb:1:in `<top (required)>'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:457:in `load'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:457:in `block in load_file'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:647:in `new_constants_in'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:456:in `load_file'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:354:in `require_or_load'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:494:in `load_missing_constant'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:184:in `const_missing'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/inflector/methods.rb:261:in `const_get'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/inflector/methods.rb:261:in `block in constantize'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/inflector/methods.rb:259:in `each'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/inflector/methods.rb:259:in `inject'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/inflector/methods.rb:259:in `constantize'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:566:in `get'
... 48 levels...
    from (irb):1
    from /Users/michael/.rbenv/versions/2.3.1/bin/irb:11:in `<top (required)>'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:63:in `load'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:63:in `kernel_load'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/cli/exec.rb:24:in `run'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/cli.rb:304:in `exec'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor.rb:359:in `dispatch'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/vendor/thor/lib/thor/base.rb:440:in `start'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/cli.rb:11:in `start'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/exe/bundle:27:in `block in <top (required)>'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/lib/bundler/friendly_errors.rb:98:in `with_friendly_errors'
    from /Users/michael/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-1.12.5/exe/bundle:19:in `<top (required)>'
    from /Users/michael/.rbenv/versions/2.3.1/bin/bundle:23:in `load'
    from /Users/michael/.rbenv/versions/2.3.1/bin/bundle:23:in `<main>'

@sudoremo
Copy link

We're experiencing similar issues with things like require_relative 'config/environment'. Any news / insights on why rails behaves differently in this case?

@NullVoxPopuli
Copy link

This happens on Rails 5.0.0.1 as well -- whenever the code changes. If I don't change any code, I don't have to restart the server.

@jtomaszewski
Copy link

Prefixing :: constants in my callbacks in ApplicationController helped for me. Similar to #2490 (comment) . Very annoying issue to fix, eh!

@kimroen
Copy link

kimroen commented Nov 22, 2016

Prefixing all the contants in our ApplicationController is what fixed this for us as well.

@varyonic
Copy link
Contributor

Interesting that this was reported shortly after d7a3ea9

@seanlinsley
Copy link
Contributor

Yeah, it's likely a bug in how Rails auto-loads files. In particular, that commit made it so the file names for models and AA config files are identical.

@besi
Copy link

besi commented Sep 21, 2017

I am using activeadmin-1.1.0 with rails-4.2.2 and ruby 2.2.1p85.
When I ran bin/rails g I got the error:

Circular dependency detected while autoloading constant AdminUser

I did that @jtomaszewski suggested and renamed admin_user.rb to admin_users.rb.
I also had to rename admin/news.rb to admin/newss.rb (Yes, that's 'ss'), before I could run the generator again.

I'd suggest to re-open this issue.

@RocketPuppy
Copy link

If people are still encountering this (like I am with Rails 5.1.4 and ActiveAdmin 1.1.0) and coming to this ticket from google, you can fix this without renaming or fully qualifying classes. Just exclude app/admin from the eager loaded (or auto loaded) paths. It looks something like this:

config.eager_load_paths = Dir.glob("#{Rails.root}/app/*").reject do |path|
  path.include?("admin")
end

From here: http://guides.rubyonrails.org/configuring.html.

config.eager_load_paths accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. Defaults to every folder in the app directory of the application.

@Dchamel
Copy link

Dchamel commented Dec 16, 2017

Hello, everyone. I have the same problem as i thought in issues

/.rvm/gems/ruby-2.3.1/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:508:in `load_missing_constant': Circular dependency detected while autoloading constant AdminUser (RuntimeError)

Rails v 5.1.4, Ruby v 2.3.1p112, ActiveAdmin 1.1.0
I see this problem when i tried to install active admin by command
"rails g active_admin:install"
and when try to start rails server

I tried to rename "app/admin/admin_user.rb" but nothing happen.
Listing issues few hours but cant understand what to do and how to fix it.

@rafaelsales
Copy link

Prepending :: to referenced classes in my ApplicationController solved my issue!
https://stackoverflow.com/a/18423438/2701824

@hdoan741
Copy link

I found out the issue was that InheritedResources::Base were not reloaded. Although ActiveAdmin did all the reloading correctly(*), the base class it used wasn't refreshed and still pointed to out-dated ApplicationController.

It looks like we need to add mechanism to InheritedResources gem (also owned by ActiveAdmin) to do reloading correctly.

(byebug) Manage::PlatformSurveysController.superclass.superclass.superclass
InheritedResources::Base
(byebug) Manage::PlatformSurveysController.superclass.superclass.superclass.superclass == ApplicationController
false

ActiveAdmin reloaded the classes correctly in here

unload_active_admin = -> { ActiveAdmin.application.unload! }

@hdoan741
Copy link

When I dig into this further, it turns out that ActiveAdmin's own controllers are also not reloaded properly. It is this whole tree that need to be unload & reloaded. I've attempted to do that manually in my app without success.

ActiveAdmin::ResourceController < ActiveAdmin::BaseController < InheritedResources::Base

Still have to rely on the hack in this issue to work-around it.

@ptiforka
Copy link

ptiforka commented Apr 2, 2020

Prefixing all the constants in our ApplicationController is what fixed this for us as well.

rails 5.2.1
active admine -> 1.4.1
ruby 2.4.1p111

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

No branches or pull requests