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

ApplicationController and Helpers are not being reloaded in Dev Env #697

Closed
ghost opened this issue Oct 28, 2011 · 43 comments
Closed

ApplicationController and Helpers are not being reloaded in Dev Env #697

ghost opened this issue Oct 28, 2011 · 43 comments

Comments

@ghost
Copy link

ghost commented Oct 28, 2011

why is the application_controller cached?
and how can i disable this?

cheers

@groe
Copy link

groe commented Mar 14, 2012

What exactly is the problem; what do you mean? And how is (caching of) your ApplicationController related to ActiveAdmin?

@pcreux pcreux closed this as completed May 3, 2012
@ghost
Copy link
Author

ghost commented May 8, 2012

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

@elia
Copy link
Member

elia commented May 15, 2012

@pcreux I'm having the same problem (v0.4.3)

@pcreux
Copy link
Contributor

pcreux commented May 15, 2012

@fu-media It was closed because you didn't give any details. :)

@pcreux pcreux reopened this May 15, 2012
@pcreux
Copy link
Contributor

pcreux commented May 15, 2012

Could you guys give a try to v0.4.4 with the latest version of inherited resources. This bug might come from inherited resources.

@ghost
Copy link
Author

ghost commented May 15, 2012

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

@elia
Copy link
Member

elia commented May 15, 2012

@pcreux I switched to head and application_controller remains cached, I'll try a bundle update inherited_resources and tell you what happens :)

@latortuga
Copy link
Contributor

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).

@elia
Copy link
Member

elia commented May 15, 2012

@pcreux me too, on head activeadmin and latest inherited_resources I get cached application_controller methods

@pcreux
Copy link
Contributor

pcreux commented May 15, 2012

@gregbell was saying that the latest version of Inherited Resources would fix this issue in #342. Looks like he was wrong. :)

@pcreux
Copy link
Contributor

pcreux commented May 15, 2012

@fu-media I don't know why it's cached.

@jpmckinney
Copy link
Contributor

Experiencing this as well.

@ddidier
Copy link

ddidier commented Nov 21, 2012

+1

@seanlinsley
Copy link
Contributor

Curiously, helpers will reload if you manually define them

ActiveAdmin.register Blah do
  controller { helper BlahHelper }
end

@seanlinsley
Copy link
Contributor

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.

@seanlinsley
Copy link
Contributor

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

@jpmckinney
Copy link
Contributor

Still an issue in 0.6.0

@seanlinsley
Copy link
Contributor

It's possible that #1935 will fix this, though I haven't checked.

@exAspArk
Copy link

exAspArk commented Oct 3, 2013

To update your helpers automatically, you can temporary hack it like:

Dir["#{ Rails.root }/app/helpers/*.rb"].each { |file| require file }

@a-chernykh
Copy link
Contributor

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

@seanlinsley
Copy link
Contributor

The solution probably lies deep in Rails' autoloading code :octocat:

a-chernykh added a commit to a-chernykh/active_admin that referenced this issue Jan 28, 2014
…directory

In order to get files automatically reloaded in Rails, these files should be under
`ActiveSupport::Dependencies.autoload_paths` directory. `Rails::Engine` adds
`app/controllers` path automatically to `autoload_paths`.

Reference: rails/rails#12195 (comment)

Closes activeadmin#697
a-chernykh added a commit to a-chernykh/active_admin that referenced this issue Jan 28, 2014
In order to get files automatically reloaded in Rails, these files should be under `ActiveSupport::Dependencies.autoload_paths` directory. `Rails::Engine` adds `app/controllers` path automatically to `autoload_paths`.

Reference: rails/rails#12195 (comment)

Closes activeadmin#697
@krukgit
Copy link

krukgit commented Mar 12, 2015

Still a problem in 1.0.0.pre1

@chancancode
Copy link
Contributor

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!

@timoschilling
Copy link
Member

@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.

@damienh
Copy link

damienh commented Apr 21, 2015

1+ on this.

@jvaill
Copy link

jvaill commented May 3, 2015

I took a stab at fixing this! PR is linked just above. 😄

@timoschilling
Copy link
Member

Some notes from @jvaill from #3927:

Just quickly brainstorming, off the top of my head I can think of a few other feasible solutions:

  1. Add the entire lib/ directory to ActiveSupport::Dependencies.autoload_paths and let Rails handle autoloading and reloading. This has the disadvantage of unloading all files inside of lib/ on each request.
  2. Move the controllers to a lib/controllers/ directory and add that to ActiveSupport::Dependencies.autoload_paths.
  3. See if we can use ActiveSupport::Dependencies.explicitly_unloadable_constants to get Rails to explicitly unload the controllers after each request.
  4. ? 😄

If we'd rather not shuffle files around, then looking into the third option might be worth it.

@timoschilling
Copy link
Member

@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.

@lakim
Copy link
Contributor

lakim commented Feb 18, 2016

There is a very interesting rails issue on how the controllers are supposed to be loaded in gems like AA:
rails/rails#12195

@seanlinsley
Copy link
Contributor

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...

@seanlinsley
Copy link
Contributor

Well the Mass gem isn't reporting any references.

ids = ObjectSpace.each_object(ActiveAdmin::Resource).map{ |r| r.controller.object_id }
Mass.references Mass[ids.first]
 => {"ActiveAdmin::Resource#70279696346980"=>["@controller"]} 

ActiveAdmin.unload!

Mass.references Mass[ids.first]
 => {}

@seanlinsley
Copy link
Contributor

This didn't seem to help:

ActiveSupport::Dependencies.explicitly_unloadable_constants << 'ActiveAdmin::BaseController'

@glebtv
Copy link
Contributor

glebtv commented Sep 20, 2018

Might be related - rails code reloading becomes slower with each reload, when anything is present in app/admin folder

To reproduce:

 100.times { puts Benchmark.measure { reload! } }

For one app I have, with 100+ activeadmin modules, it is 2s for first reload, 4s for second, and up to 2-3 minutes to complete hang in 10-15 reloads.

@mvoropaiev
Copy link

@glebtv not sure if this is the right issue to report, but i am experiencing the same issue with AA 1.4.3, rails 5.2.2.
Forced to re-start rails app after a few changes while developing admin part of application or otherwise it becomes unusable.
Is there something that can be done to address it? Thanks.

@deivid-rodriguez
Copy link
Member

No news here, but I've seen several development environment memory leaks fixed in Rails recently, so maybe Rails 6 brings new hope here.

In particular, there's rails/rails#32892 and a related open PR. It'd be good if some hitting this problem could try that patch!

@mvoropaiev
Copy link

Trying a patch from merged PR https://github.com/rails/rails/pull/31442/files indeed increased reload speed of application, but now activeadmin does not reloads in dev env on files (app/admin/*) change, changes respected only after server restart, any idea where to dig regards this?
Thanks!

@kaneru
Copy link

kaneru commented Dec 18, 2019

Hello, everyone! Facing this issue in my project. Really need to DRY my code in some AA views with helpers. Is there any temporary hack for this issue? This hack seems not to work for me:

To update your helpers automatically, you can temporary hack it like:

Dir["#{ Rails.root }/app/helpers/*.rb"].each { |file| require file }

@sethdeckard
Copy link

Given the age of this bug, I'm assuming this may not ever be fixed. What is a good alternative approach to using helpers in AA these days?

@ndbroadbent
Copy link
Contributor

I just ran into this as well, and was wondering why I had to restart my server after any change in my helper file. I was just wondering if this is easier now with Zeitwerk and Rails 6 / Rails 7?

@rogerkk
Copy link
Contributor

rogerkk commented Nov 2, 2022

@ndbroadbent I still have to restart when i make changes to helpers, even under Zeitwerk on Rails 6.

@javierjulio javierjulio closed this as not planned Won't fix, can't repro, duplicate, stale Mar 12, 2023
@jcarlson
Copy link

Can this issue be reopened? This is still an issue with the following configuration:

  • Ruby 3.0.2
  • Rails 6.1.4
  • active admin 2.14.0
  • inherited_resources 1.13.1

This issues is also mentioned in the "Gotchas" section of the docs which, by the way, are not linked from the table of contents.

@javierjulio
Copy link
Member

The default branch is ready for a v4 release so I would be very open to these type of changes, I’m just not familiar with Rails autoloading to know what’s safe. I’ve been developing the new version of ActiveAdmin so I’ve experienced the pain of having to restart the dev server when making any changes. Since I've extracted partials I’ve had much better success. I would love to do the same with controllers or other files. If you’d like to help please let me know.

@jaynetics
Copy link
Contributor

putting this in an initializer is a bit hacky but does the trick as a workaround.

Rails.application.reloader.to_prepare do
  Arbre.send(:remove_const, :Context)
  load $LOADED_FEATURES.grep(%r{/arbre/context\.rb}).sole
  Arbre::Context.prepend(MyHelper)
end

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