I'm testing activeadmin with Rails 4 and got it working nicely in development. But in production, sidebar is shown twice. And the resource path is generated wrong in case of belongs_to dependency.
ActiveAdmin.register Tournament do
end
ActiveAdmin.register ScheduledMatch do
belongs_to :tournament
end
The admin path generated automatically for ScheduledMatch
by inherited_resources for actions, filter is admin_tournament_tournament_scheduled_matches_path
instead of admin_tournament_scheduled_matches_path
(Parent tournament is added twice) because of which it is failing in production.
The above problems show up only in production and not in development
My Gemfile (According to #2326 )
gem 'activeadmin', github: 'gregbell/active_admin', branch: 'rails4'
gem 'ransack', github: 'ernie/ransack', branch: 'rails-4'
gem 'inherited_resources', github: 'josevalim/inherited_resources'
gem 'formtastic', github: 'justinfrench/formtastic'
I haven't been able to reproduce this. Can you confirm that this still happens, even with a clean Rails app?
Haven't tried it with a clean Rails app. Will try out and update.
Regards,
Gautham
Fansy - For Fantasy cricket
nuts.https://play.google.com/store/apps/details?id=com.gauthamns.fantasycricket
One touch expenser.
https://play.google.com/store/apps/details?id=org.blrdroid.expenseapp
On Tue, Jul 9, 2013 at 2:55 AM, Sean Linsley [email protected]:
I haven't been able to reproduce this. Can you confirm that this still
happens, even with a clean Rails app?—
Reply to this email directly or view it on GitHubhttps://github.com/gregbell/active_admin/issues/2329#issuecomment-20637276
.
I've got similar issue with action items on production, rails 4.
Custom added action items are shown twice on production, on development it's all fine
action_item :only => :show do
link_to('Add new keyword', new_admin_keyword_path)
end
My gemfile is same as in #2326
I'm having this problem too, it looks like its to do with Rails eager loading the app/admin folder in addition to ActiveAdmin loading it. If i set config.eager_load = false
in production.rb then duplication doesn't happen but then this also disables threadsafe in Rails 4 which otherwise works fine in our app
I've just tried this with a fresh Rails 4 app, and I'm not getting duplicate action items there.
@ball-hayden, I'm confused. In #2346 you said this is a problem. But here you said it isn't.
Are you saying that your preexisting app has the problem, but a fresh app does not? In that case, it may be a problem with the configuration options you have set in your app.
Apologies - Yes... #2346 was with an existing app that I have upgraded from Rails 3.2.13.
I've just tried with a completely fresh Rails 4 app, and the problem doesn't occur.
I've done a bit of digging with byebug, and found that as @marcroberts suspected files in app/admin
are indeed being eager loaded.
Unfortunately, the issue appears not to be because of config in the old app, but rather an issue with file naming.
For the fresh Rails 4 app, running rails generate active_admin:install
creates app/admin/admin_user.rb
. This file is only loaded once (by ActiveAdmin), and hence any calls to action_item only happen once.
My existing app (for whatever reason) has several files that were plural rather than singular (in my case, app/admin/tracks
). Files in app/admin
in plural form appear to be loaded twice.
The issue appears to be in lib/active_support/dependencies.rb
on line 287.
If the singular form is used (e.g. admin_user), search_for_file
incorrectly finds app/models/admin_user.rb
If the plural form is used (e.g. admin_users), search_for_file
returns nil, hence require_or_load
attempts to require admin_users
, which then requires our file, app/admin/admin_users.rb
. As AA has already loaded this file, any calls to action_item happen twice, hence our duplicates.
Although I haven't tried it, I suspect this may also cause issues with any AA definition files that don't have another file in autoload_paths
with the same name.
TL;DR, changing filenames to match those of the model (i.e. singular) seems to be a work around - renaming my file from app/admin/tracks.rb
to app/admin/track.rb
appears to have fixed the issue.
Oh that's interesting. Looks like this is also what caused #2317 (/cc @jarinudom)
Thanks for running this down @ball-hayden!
+1 for the work around.
thanks @ball-hayden
Ah... this is my fault. Specifically:
- # Since we're dealing with all our own file loading, we need
- # to remove our paths from the ActiveSupport autoload paths.
- # If not, file naming becomes very important and can cause clashes.
- def remove_active_admin_load_paths_from_rails_autoload_and_eager_load
- ActiveSupport::Dependencies.autoload_paths.reject!{|path| load_paths.include?(path) }
- # Don't eagerload our configs, we'll deal with them ourselves
- Rails.application.config.eager_load_paths = Rails.application.config.eager_load_paths.reject do |path|
- load_paths.include?(path)
- end
+ # Since the default load path, app/admin, is alphabetically before app/models, we have
+ # to remove it from the host app's +autoload_paths+ to prevent missing constant errors.
+ def remove_active_admin_load_paths_from_rails_autoload
+ ActiveSupport::Dependencies.autoload_paths.reject!{ |path| load_paths.include? path }
end
From the commit message for 431b293dc8cb34a4a65118c66e4a81afd9124ba3:
#### Removed 99% of our custom class reloader in favor of Rails reloading
Note: I removed the code that purges `app/admin` from Rails' `eager_load_paths`
since there were no bad effects of doing so. Only the code that does this for
Rails' `autoload_paths` seems necessary.
Apparently, that wasn't the case. I wonder if there's a way to write tests to ensure a given file is only loaded once...
@ball-hayden the reason why some of your app/admin
files were plural was likely because that used to be what the AA generator created.
So I changed the demo project referenced in #2386 to use singular form of the file names and it stopped the double loading, however, the route/path for the nested resource button is still wonky: "new_admin_event_event_event_registration_path" instead of the expected "new_admin_event_event_registration_path"
BTW I just opened a ticket to deal with the second problem originally described: https://github.com/josevalim/inherited_resources/issues/306
The admin path generated automatically for
ScheduledMatch
by inherited_resources for actions, filter isadmin_tournament_tournament_scheduled_matches_path
instead ofadmin_tournament_scheduled_matches_path
(Parent tournament is added twice) because of which it is failing in production.
Thanks for the discussion on this issue; I deployed a rails 4 version of our app to our staging environment and freaked out a bit until I found this thread. Renaming the app/admin files in singular form fixed both duplicate buttons in our admin navigation and also missing routes that had duplicate nested model names in them (new_admin_even_event_event_registration_path
).
I'm also having the bug with the sidebar being shown twice as well as action items being shown twice. Renaming to a singular form has not fixed the issue for me. This issue sprang up when I started using partials for the sidebars.
To confirm, @spinlock99 are you using Rails 4?
@Daxter Nope, we're using 3.2.13.
issue still present in rails 4. latest rails4 branch as of today with up to date dependencies (stable versions and rc2 formtastic)
Everyone, please try out #2484:
gem 'activeadmin', github: 'Daxter/active_admin', branch: 'bugfix/2329-eager_load_paths'
I've just reverted my "de-pluralizing" commit and the duplicates haven't re-appeared, so it looks like this your PR has fixed it.
This has been fixed on the rails4 branch.
So how do I fix this bug? Upgrade activeadmin? To what version?
I'm in the same situation as @ball-hayden : migrating legacy code from Rails 3 (to 5.0.1) with pluralized activeadmin models. I'm using 1.0.0.pre5
. This issue (duplicate sidebar
s) affects me whenever config.eager_load = true
, which is the case of production/staging/etc.
I have tested singularized filenames with no success.
@lbrito1 use the pre4 version from the master branch:
In your Gemfile:
~
gem 'activeadmin', github: 'activeadmin'
~
Update your bundle:
~
bundle install
bundle list | grep activeadmin
~
See: " * activeadmin (1.0.0.pre4 78324a8)" in output
Thanks for the answer @mwlang . Indeed, using 1.0.0.pre4 solves the issue, but I am rather reticent on using that snapshot instead of pre5 since there were quite a lot of changes made in between.
@gvc did a monkeypatch on ActiveAdmin::Application#register
(pre5 branch) which solves the issue and will post it here shortly.
The patch works only onRuby > 2 and assumes that you don't register the same resource with various definitions more than once. Having said that, here it is:
module UniqueResourceRegister
def register(resource, options = {}, &block)
unless registered_resources.include?(resource)
registered_resources << resource
super
end
end
private
def registered_resources
@registered_resources ||= []
end
end
ActiveAdmin::Application.prepend(UniqueResourceRegister)
I'm still having this issue on production.
Gemfile:
ruby '2.2.4'
gem 'rails', '4.2.0'
gem 'activeadmin', '~> 1.0.0.pre4'
I can't use gem 'activeadmin', github: 'activeadmin'
(with github:) due to lack of permissions in our deployment area.
It looks as though 1.0.0.pre4 is on rubygems, but it doesn't seem to be using it if it's fixed there?
@davidwparker If your deployment area is restricted, then you'll want to vendor your gems so your dependency on external gem servers is removed. Take a look at "bundle package" command for this. If you're using capistrano, also look at setting "bundle_flag" to "--local" With these options, you can still utilize gems no matter where their sources are. As long as your development environment can build the vendor cache (and you commit cache to repo), you'll be able to deploy to your servers.
I still see this with AA 1.0.1 and 1.1.0 (on Ruby 2.3.3, Rails 4.2.9) when config.eager_load
is true. Removing app/admin
from the eager load path didn't help, but the above patch (UniqueResourceRegister
) did. While it works, it'd be nice to fix this in general.
Here are the backtraces for both requires. I haven't had the time to investigate more. Upgrading to devise 4 had no effect, however.
First call
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `block in load'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:240:in `load_dependency'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:231:in `block in load'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/error.rb:41:in `capture'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:231:in `load'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:223:in `block in load!'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:223:in `each'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:223:in `load!'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin/application.rb:245:in `routes'
/usr/local/bundle/gems/activeadmin-1.0.0/lib/active_admin.rb:80:in `routes'
/usr/src/app/config/routes.rb:203:in `block in \u003ctop (required)\u003e'
/usr/local/bundle/gems/actionpack-4.2.9/lib/action_dispatch/routing/route_set.rb:432:in `instance_exec'
/usr/local/bundle/gems/actionpack-4.2.9/lib/action_dispatch/routing/route_set.rb:432:in `eval_block'
/usr/local/bundle/gems/actionpack-4.2.9/lib/action_dispatch/routing/route_set.rb:410:in `draw'
/usr/src/app/config/routes.rb:1:in `\u003ctop (required)\u003e'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `block in load'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:240:in `load_dependency'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/routes_reloader.rb:40:in `block in load_paths'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/routes_reloader.rb:40:in `each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/routes_reloader.rb:40:in `load_paths'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/routes_reloader.rb:16:in `reload!'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application.rb:170:in `reload_routes!'
/usr/local/bundle/gems/devise-3.5.10/lib/devise/rails.rb:14:in `block in \u003cclass:Engine\u003e'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/lazy_load_hooks.rb:36:in `execute_hook'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/lazy_load_hooks.rb:45:in `block in run_load_hooks'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/lazy_load_hooks.rb:44:in `each'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/lazy_load_hooks.rb:44:in `run_load_hooks'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/finisher.rb:55:in `block in \u003cmodule:Finisher\u003e'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `instance_exec'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `run'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:55:in `block in run_initializers'
/usr/local/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
/usr/local/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
/usr/local/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `each'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `call'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
/usr/local/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:54:in `run_initializers'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application.rb:352:in `initialize!'
/usr/src/app/config/environment.rb:5:in `\u003ctop (required)\u003e'
config.ru:4:in `require'
config.ru:4:in `block in \u003cmain\u003e'
/usr/local/bundle/gems/rack-1.6.8/lib/rack/builder.rb:55:in `instance_eval'
/usr/local/bundle/gems/rack-1.6.8/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `\u003cmain\u003e'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn.rb:48:in `eval'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn.rb:48:in `block in builder'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:768:in `build_app!'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:137:in `start'
/usr/local/bundle/gems/unicorn-4.9.0/bin/unicorn:126:in `\u003ctop (required)\u003e'
/usr/local/bundle/bin/unicorn:17:in `load'
/usr/local/bundle/bin/unicorn:17:in `\u003cmain\u003e'
Second call
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `require'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `block in require'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:240:in `load_dependency'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `require'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:360:in `require_or_load'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:317:in `depend_on'
/usr/local/bundle/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:233:in `require_dependency'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:472:in `block (2 levels) in eager_load!'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:471:in `each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:471:in `block in eager_load!'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:469:in `each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:469:in `eager_load!'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/engine.rb:346:in `eager_load!'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/finisher.rb:56:in `each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application/finisher.rb:56:in `block in \u003cmodule:Finisher\u003e'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `instance_exec'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `run'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:55:in `block in run_initializers'
/usr/local/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
/usr/local/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
/usr/local/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `each'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `call'
/usr/local/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
/usr/local/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
/usr/local/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/initializable.rb:54:in `run_initializers'
/usr/local/bundle/gems/railties-4.2.9/lib/rails/application.rb:352:in `initialize!'
/usr/src/app/config/environment.rb:5:in `\u003ctop (required)\u003e'
config.ru:4:in `require'
config.ru:4:in `block in \u003cmain\u003e'
/usr/local/bundle/gems/rack-1.6.8/lib/rack/builder.rb:55:in `instance_eval'
/usr/local/bundle/gems/rack-1.6.8/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `\u003cmain\u003e'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn.rb:48:in `eval'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn.rb:48:in `block in builder'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:768:in `build_app!'
/usr/local/bundle/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:137:in `start'
/usr/local/bundle/gems/unicorn-4.9.0/bin/unicorn:126:in `\u003ctop (required)\u003e'
/usr/local/bundle/bin/unicorn:17:in `load'
/usr/local/bundle/bin/unicorn:17:in `\u003cmain\u003e'
@phillipoertel -
Since we didn't want to mess with bundle changes, our quickest super bad hack to fix this was to use CSS:
.ouradminselector .action_items span.action_item:nth-child(2) {
display: none;
}
It's less than ideal, but it works.
@davidwparker Nice hack, didn't think of doing it in CSS :-)
Same bug with ActiveAdmin 2.2.0
same bug with ActiveAdmin 2.7.0
I put all activeadmin files as plural (because I've seen the autogenerated admin_users.rb.
putting in singular case the file that was creating the bug solved everything.
Most helpful comment
So how do I fix this bug? Upgrade activeadmin? To what version?