1
votes

I am converting a rails app from a single application into several engines.

I am attempting to moving ActiveAdmin into the engine running the front end application.

The stack is:

  • Ruby 4.2.2
  • Rails 4.1
  • Devise 3.5.1
  • ActiveAdmin from the github master branch.

I have ActiveAdmin included in the gemspec:

s.add_dependency 'activeadmin'

In my gemfile:

gem 'activeadmin', github: 'activeadmin'

In my web_app/lib folder the file web_app.rb looks like this:

require "web_app/engine"

module WebApp
  extend ActiveSupport::Autoload
  autoload :Admin
end

The engine file in web_app/lib/web_app contains the following:

require 'devise'
require 'activeadmin'

module WebApp
  class Engine < ::Rails::Engine
    isolate_namespace WebApp

    initializer "web_app.assets.precompile" do |app|
      app.config.assets.precompile += %w( web_app/common.css web_app/desktop.css eb_app/common_tablet_mobile.css web_app/mobile.css web_app/tablet.css ie/json2.js )
    end

    initializer :web_app do
      ActiveAdmin.application.load_paths += Dir[File.dirname(__FILE__) + '/admin']
    end
  end
end

The routes file looks like this:

WebApp::Engine.routes.draw do

  ActiveAdmin.routes(self)
  ...
end

All of the ActiveAdmin resources are stored in web_app/lib/web_app/admin.

After logging in as an admin user the following error is thrown:

cannot load such file -- web_app/admin

activesupport (4.1.11) lib/active_support/inflector/methods.rb:240:in `block in constantize'
activesupport (4.1.11) lib/active_support/inflector/methods.rb:236:in `constantize'
activesupport (4.1.11) lib/active_support/dependencies.rb:552:in `get'
activesupport (4.1.11) lib/active_support/dependencies.rb:583:in `constantize'
actionpack (4.1.11) lib/action_dispatch/routing/route_set.rb:78:in `controller_reference'
actionpack (4.1.11) lib/action_dispatch/routing/route_set.rb:68:in `controller'
actionpack (4.1.11) lib/action_dispatch/routing/route_set.rb:46:in `call'
actionpack (4.1.11) lib/action_dispatch/journey/router.rb:73:in `block in call'
actionpack (4.1.11) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.1.11) lib/action_dispatch/routing/route_set.rb:692:in `call'
railties (4.1.11) lib/rails/engine.rb:514:in `call'
railties (4.1.11) lib/rails/railtie.rb:194:in `method_missing'
actionpack (4.1.11) lib/action_dispatch/journey/router.rb:73:in `block in call'
actionpack (4.1.11) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.1.11) lib/action_dispatch/routing/route_set.rb:692:in `call'
bullet (4.14.7) lib/bullet/rack.rb:10:in `call'
rack-mobile-detect (0.4.0) lib/rack/mobile-detect.rb:164:in `call'
warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
warden (1.2.3) lib/warden/manager.rb:34:in `call'
rack (1.5.5) lib/rack/etag.rb:23:in `call'
rack (1.5.5) lib/rack/conditionalget.rb:25:in `call'
rack (1.5.5) lib/rack/head.rb:11:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/flash.rb:254:in `call'
rack (1.5.5) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.5.5) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/cookies.rb:562:in `call'
activerecord (4.1.11) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.1.11) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call'
activerecord (4.1.11) lib/active_record/migration.rb:380:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.1.11) lib/active_support/callbacks.rb:82:in `run_callbacks'
actionpack (4.1.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/reloader.rb:73:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.1.11) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.1.11) lib/rails/rack/logger.rb:22:in `call'
request_store (1.1.0) lib/request_store/middleware.rb:8:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.5) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.5) lib/rack/runtime.rb:17:in `call'
activesupport (4.1.11) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
rack (1.5.5) lib/rack/lock.rb:17:in `call'
actionpack (4.1.11) lib/action_dispatch/middleware/static.rb:84:in `call'
rack (1.5.5) lib/rack/sendfile.rb:112:in `call'
railties (4.1.11) lib/rails/engine.rb:514:in `call'
railties (4.1.11) lib/rails/application.rb:144:in `call'
rack (1.5.5) lib/rack/lock.rb:17:in `call'
rack (1.5.5) lib/rack/content_length.rb:14:in `call'
rack (1.5.5) lib/rack/handler/webrick.rb:60:in `service'
/Users/kfranzen/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
/Users/kfranzen/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
/Users/kfranzen/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'

Directory listing for the engine

wep_app/
  app/
    assets/
    controllers/
    helpers/
    mailers/
    models/
    views/
  config/
    initializers/
      active_admin.rb
  lib/
    web_app.rb
    web_app/
      engine.rb
      version.rb
      admin/
        resource files
    tasks/
  spec/

UPDATE with narrowed down version of the issue:

I narrowed down the issue to loading ActiveAdmin in a mounted engine.

First I changed the engine documented above to a full engine so all routes are inherited by the parent app. This resolved the primary issue with accessing the ActiveAdmin routes.

So I have moved ActiveAdmin and other Admin specific code to a separate engine 'admin' engine.

The admin.gemspec file includes:

s.add_dependency 'activeadmin'

The Gemfile includes the following line to pull the current version:

gem 'activeadmin', github: 'activeadmin'

The admin/lib folder contains the file admin.rb looks like this:

require "admin/engine"

module Admin
  extend ActiveSupport::Autoload
end

The engine file in admin/lib/admin contains the following:

require 'activeadmin'
require 'activeadmin_hstore_editor'
require 'active_admin_csv_import'
require 'ckeditor'

module Admin
  class Engine < ::Rails::Engine

    initializer "admin.assets.precompile" do |app|
      app.config.assets.precompile += %w( vendor.css vendor.js ckeditor/* )
    end

    initializer :admin do
      ActiveAdmin.application.load_paths += Dir[File.dirname(__FILE__) + '/admin']
    end
  end
end

The routes file looks like this:

Admin::Engine.routes.draw do

  ActiveAdmin.routes(self)

end

All of the ActiveAdmin resources are stored in web_app/lib/admin/admin.

ActiveAdmin works correctly as long as the engine is loaded without:

isolate_namespace Admin

If isolate_namespace is added then the errors reported in the previous section occur.

When loading the engine as a mountable engine the parent Rails.application.routes contain the following:

mount Admin::Engine, at: '/', as: 'admin'
2
provide the stacktrace for cannot load such file -- web_app/admin - Timo Schilling
Thanks for taking a look. Sorry about the oversight. - Kirk
please provide a directory listing of your engine - Timo Schilling

2 Answers

1
votes

I might me a little late, but I found a solution that worked for me and I think could work for everyone facing this issue. It's quite hacky, but goes straight to the point of the problem...

I am using Rails 5, my engine is called MyEngine, and I am using the default ActiveAdmin namespace of :admin.

The error I get when going to the /admin path is this:

Routing Error uninitialized constant MyEngine::Admin

The thing is that it is looking for Admin inside the Namespace of my mountable engine, because that's how they work, they encapsulate everything in its namespace, but the Admin namespace exists in the root (I checked using rails console), so I just went to my engine's routes.rb file and at the very end (after the MyEngine::Engine.routes.draw do .... end block) I just appended this line:

MyEngine::Admin = Admin

After doing this, it just works!

0
votes

Your problem is here:

module WebApp
  extend ActiveSupport::Autoload
  autoload :Admin
end

What does Admin is?

  • If you mean ActiveAdmin, you don't need to autoload it in this way, you only need to require 'activeadmin' on the top of the file.

  • If it's a constant of your App, you need to place it in web_app/admin.rb, or you need to require a file that contains it.

I hope that could help you, otherwise write a comment and I will try to help you more.