Rails cannot find module if config.cache_classes = true

I have a gem that mounts as a motor in my rails application via routes.rb and Gemfile . Here are the important parts:

Gemfile Applications

 source 'https://rubygems.org' gem 'rails', '3.2.9' gem 'mysql2' group :assets do gem 'sass-rails' gem 'coffee-rails' end gem 'jquery-rails' gem "common_client", path: "../common-client" 

Routes.rb application

 mount CommonClient::Engine => "", :as => 'shared' 

gem routes.rb

 get '/register' => 'session#new_registration' 

gems SessionController

 require 'common_client/session_controller_base' class SessionController < ApplicationController include CommonClient::SessionControllerBase end 

gems SessionControllerBase

 module CommonClient module SessionControllerBase def new_registration #some code goes here end end 

This works great in development, and the rails can find CommonClient::SessionController and execute the new_registration action whenever a visitor enters the /register route. But in Production, the rails cannot find CommonClient::SessionController and generate the following error:

 $ RAILS_ENV=production rails s => Booting WEBrick => Rails 3.2.9 application starting in production on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2012-12-09 03:27:29] INFO WEBrick 1.3.1 [2012-12-09 03:27:29] INFO ruby 1.9.3 (2012-10-12) [x86_64-linux] [2012-12-09 03:27:29] INFO WEBrick::HTTPServer#start: pid=4248 port=3000 Started GET "/" for 127.0.0.1 at 2012-12-09 03:28:17 +0530 Processing by WelcomeController#index as HTML Redirected to localhost:3000/register Filter chain halted as :check_credentials rendered or redirected Completed 302 Found in 267ms (ActiveRecord: 0.0ms) Started GET "/register" for 127.0.0.1 at 2012-12-09 03:28:18 +0530 ActionController::RoutingError (uninitialized constant CommonClient::SessionController): vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/inflector/methods.rb:230:in `block in constantize' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/inflector/methods.rb:229:in `each' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/inflector/methods.rb:229:in `constantize' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/routing/route_set.rb:69:in `controller_reference' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/routing/route_set.rb:54:in `controller' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/routing/route_set.rb:32:in `call' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:68:in `block in call' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `each' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/routing/route_set.rb:601:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/engine.rb:479:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/railtie/configurable.rb:30:in `method_missing' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:68:in `block in call' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `each' vendor/bundles/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/routing/route_set.rb:601:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/etag.rb:23:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/conditionalget.rb:25:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/head.rb:14:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/params_parser.rb:21:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/flash.rb:242:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:205:in `context' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:200:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/cookies.rb:341:in `call' vendor/bundles/ruby/1.9.1/gems/activerecord-3.2.9/lib/active_record/query_cache.rb:64:in `call' vendor/bundles/ruby/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:405:in `_run__4296103602150594596__call__1936882885794917979__callbacks' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:405:in `__run_callback' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:385:in `_run_call_callbacks' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:81:in `run_callbacks' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/callbacks.rb:27:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/remote_ip.rb:31:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:32:in `call_app' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:16:in `block in call' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/tagged_logging.rb:22:in `tagged' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:16:in `call' vendor/bundles/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/request_id.rb:22:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/runtime.rb:17:in `call' vendor/bundles/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/cache/strategy/local_cache.rb:72:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/lock.rb:15:in `call' vendor/bundles/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward' vendor/bundles/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:245:in `fetch' vendor/bundles/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:185:in `lookup' vendor/bundles/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:66:in `call!' vendor/bundles/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/engine.rb:479:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/application.rb:223:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/content_length.rb:14:in `call' vendor/bundles/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/log_tailer.rb:17:in `call' vendor/bundles/ruby/1.9.1/gems/rack-1.4.1/lib/rack/handler/webrick.rb:59:in `service' /home/gaurish/.rvm/rubies/ruby-1.9.3-p286-perf/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service' /home/gaurish/.rvm/rubies/ruby-1.9.3-p286-perf/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run' /home/gaurish/.rvm/rubies/ruby-1.9.3-p286-perf/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread' ^C[2012-12-09 03:42:57] INFO going to shutdown ... [2012-12-09 03:42:57] INFO WEBrick::HTTPServer#start done. Exiting 

Now, here is the interesting part. These errors go into production, and the application works fine when I turn off code caching in production.rb . setting

 config.cache_classes = false 

All this makes me think

  • why can rails CommonClient::SessionController in env development but not in env production?
  • How does setting config.cache_classes = false make it work in production? And the rails can find CommonClient::SessionController , which he could not do before
  • What do I need to do when the rails detect CommonClient::SessionController , except for the ugly hack of disabling the code cache and reloading the entire code for each request?

Finally, I tried to explain as much as I could, but still something is unclear or additional information is required. Please leave a comment. Thanks

+4
source share
2 answers

Try updating route.rb as:

 require 'common_client' mount CommonClient::Engine => '/shared' 
+1
source

I suspect this is due to the boot order. In development mode (when cache_classes is false) Rails will load all your loadable classes for each request. This happens after the rest of the framework is initialized.

For comparison, in production mode, everything is loaded in one shot, so it is possible that your CommonClient is loaded to some other fragment of the Rails stack, and then it is hidden when Rails is loaded. Valery’s ActiveSupport hooks offer is good - what does a CommonClient rally look like? You may be able to modify your gem railtie to load your controllers after loading the ActionController, which should provide behavior much more similar to the behavior of loading Rails mode.

+2
source

All Articles