activeadmin
activeadmin copied to clipboard
ApplicationController and Helpers are not being reloaded in Dev Env
why is the application_controller cached? and how can i disable this?
cheers
What exactly is the problem; what do you mean? And how is (caching of) your ApplicationController related to ActiveAdmin?
why its closed?
if i make a change in the application_controller (for example an http_auth for the admin namespace) and i change there something, i have to restart the server. same effect with helpers. they got cache and for each change i have to restart the server
@pcreux I'm having the same problem (v0.4.3)
@fu-media It was closed because you didn't give any details. :)
Could you guys give a try to v0.4.4 with the latest version of inherited resources. This bug might come from inherited resources.
what details you want to have?
i ask why its cached. so i have to restart the server always if i change helpers or application_controller, to take effect in active_admin
its not reloaded on each request
@pcreux I switched to head and application_controller
remains cached, I'll try a bundle update inherited_resources
and tell you what happens :)
I've been on 1.3.1 of InheritedResources (the latest) for quite awhile and have had this problem ever since forever. It's kind of annoying, especially since my CanCan current_ability
method is inside the application controller. I think the helpers not being reloaded is a side-effect of the controller not being reloaded because helpers are all loaded from the application controller.
I'm on AA 0.4.3, Rails 3.2.2, Ruby 1.9.3-p194 (latest I'm aware of).
@pcreux me too, on head activeadmin and latest inherited_resources I get cached application_controller methods
@gregbell was saying that the latest version of Inherited Resources would fix this issue in #342. Looks like he was wrong. :)
@fu-media I don't know why it's cached.
Experiencing this as well.
+1
Curiously, helpers will reload if you manually define them
ActiveAdmin.register Blah do
controller { helper BlahHelper }
end
Well this is interesting:
div method(:helpers).source_location # ...gems/arbre-1.0.1/lib/arbre/element.rb21
div method(:helpers).owner # Arbre::Element
div helpers.method(:blah).source_location # ...app/helpers/blah_helper.rb12
div helpers.method(:blah).owner # BlahHelper
div "#{blah} -> #{helpers.blah}" # 1 -> 1
So it's likely that Arbre won't let go of the previously loaded helpers.
Okay, so maybe not. Here's an experiment strictly from rails console
:
app_1 = ApplicationController.object_id
derived_1 = UsersController.ancestors.detect {|a| a.to_s =~ /Appli/}.object_id
derived_1 == app_1 # => true
reload!
app_2 = ApplicationController.object_id
derived_2 = UsersController.ancestors.detect {|a| a.to_s =~ /Appli/}.object_id
derived_2 == app_2 # => false
derived_2 == derived_1 # => true
ObjectSpace._id2ref(app_1) # => ApplicationController # Shouldn't exist!!
ObjectSpace._id2ref(app_2) # => ApplicationController
It's odd that the old ApplicationController still exists... I thought it would be entirely removed from memory.
To illustrate the same thing from the browser:
# 1 changes on file edit, 3 changes on every load, 2 & 4 never change
div controller.class.object_id
div controller.class.ancestors.detect {|a| a.to_s =~ /Appli/}.object_id
div helpers.object_id
div helpers.blah.object_id
Still an issue in 0.6.0
It's possible that #1935 will fix this, though I haven't checked.
To update your helpers automatically, you can temporary hack it like:
Dir["#{ Rails.root }/app/helpers/*.rb"].each { |file| require file }
Just wanted to mention that it's still an issue. ApplicationController
is not being reloaded when activeadmin
is used (tested with dummy Rails 4.0.2 app with activeadmin
in Gemfile).
>> ActiveAdmin::Devise::SessionsController.ancestors.find { |a| a.name =~ /Appl/ }.object_id == ApplicationController.object_id
=> true
>> reload!
Reloading...
=> true
>> ActiveAdmin::Devise::SessionsController.ancestors.find { |a| a.name =~ /Appl/ }.object_id == ApplicationController.object_id
=> false # now we have 2 different ApplicationController-s
But after reloading:
>> Devise::SessionsController.ancestors.find { |a| a.name =~ /Appl/ }.object_id == ApplicationController.object_id
=> true
The solution probably lies deep in Rails' autoloading code :octocat:
Still a problem in 1.0.0.pre1
If someone can make a barebone app on github and provide the steps (manual is fine, doesn't need to be automated) to reproduce it, I can probably take a look!
@chancancode here is a test app to reproduce this bug: https://github.com/activeadmin/activeadmin_helper_reload_bug Take a look on the readme But it should be happen in every activeadmin app too.
1+ on this.
I took a stab at fixing this! PR is linked just above. :smile:
Some notes from @jvaill from #3927:
Just quickly brainstorming, off the top of my head I can think of a few other feasible solutions:
- Add the entire
lib/
directory toActiveSupport::Dependencies.autoload_paths
and let Rails handle autoloading and reloading. This has the disadvantage of unloading all files inside oflib/
on each request.- Move the controllers to a
lib/controllers/
directory and add that toActiveSupport::Dependencies.autoload_paths
.- See if we can use
ActiveSupport::Dependencies.explicitly_unloadable_constants
to get Rails to explicitly unload the controllers after each request.- ? :smile:
If we'd rather not shuffle files around, then looking into the third option might be worth it.
@chancancode can you take a look on this problem with the test app? https://github.com/activeadmin/activeadmin_helper_reload_bug Take a look on the readme But it should be happen in every activeadmin app too.
There is a very interesting rails issue on how the controllers are supposed to be loaded in gems like AA: https://github.com/rails/rails/issues/12195
Disconnecting this from the Rails reloading, I can reproduce by simply calling ActiveAdmin.unload!
ObjectSpace.each_object(ActiveAdmin::Resource).count => 17
ActiveAdmin.unload!
ObjectSpace.each_object(ActiveAdmin::Resource).count => 17
ids = ObjectSpace.each_object(ActiveAdmin::Resource).map{ |r| r.controller.object_id }
ids.count => 17
GC.start
ObjectSpace.each_object(ActiveAdmin::Resource).count => 0
ids.count{ |id| ObjectSpace._id2ref id rescue nil } => 17
ActiveAdmin::BaseController.descendants.count => 22
ObjectSpace._id2ref(ids.first).name.constantize
-> NameError: uninitialized constant Admin::UsersController
Unload currently does a lot of work to remove the objects from memory, but there must be a reference to the controller somewhere that's not being removed. If only Ruby made it easy to see the references keeping an object in memory...