I am creating a Rails Engine and I have an initializer that needs to interact with the application routes.  I had no luck just adding the initializer like this:

require "my_engine"
require "rails"

module MyEngine
  class Engine < Rails::Engine
      initializer 'my_engine.interact_with_routes' do |app|
        # meat goes here
      end
  end
end

The initializer runs, but the problem is that the routes have not been initialized in the Application object and therefore my code does not have any routes to interact with. The rails core geniuses have included a feature that allows you to pick where your initilializer should load. You can add :after or :before params like so:

require "my_engine"
require "rails"

module MyEngine
  class Engine < Rails::Engine
      initializer 'my_engine.interact_with_routes', :after=>"some_other_initializer" do |app|
        # meat goes here
      end
  end
end

I didn’t really have a clue what initializers were running inside the rails core, so with some quick cowboy coding, I added some ugly print statements to “railties/lib/rails/application.rb” inside the initializers def, so I could see what the order of the initializers and where they were coming from:

    def initializers
      initializers = Bootstrap.initializers_for(self) #BOOTSTRAP
      print_initializers(initializers)
      railties.all { |r| initializers += r.initializers } #RAILTIES
      print_initializers(initializers)
      initializers += super #SUPER
      print_initializers(initializers)
      initializers += Finisher.initializers_for(self) #FINISHER
      print_initializers(initializers)
      initializers
    end

    def print_initializers(initializers)
      initializers.each do |i|
        p i.name
      end
      p "----------------------------"
    end

Here are the results (formatted with repeats removed):

BOOTSTRAP
:load_environment_config
:load_active_support
:preload_frameworks
:initialize_logger
:initialize_cache
:set_clear_dependencies_hook
:initialize_dependency_mechanism
:bootstrap_hook
RAILTIES
"i18n.callbacks"
"active_support.initialize_whiny_nils"
"active_support.deprecation_behavior"
"active_support.initialize_time_zone"
"action_dispatch.prepare_dispatcher"
"action_view.cache_asset_timestamps"
"action_view.javascript_expansions"
"action_view.set_configs"
"action_controller.logger"
"action_controller.initialize_framework_caches"
"action_controller.set_configs"
"action_controller.deprecated_routes"
"active_record.initialize_timezone"
"active_record.logger"
"active_record.set_configs"
"active_record.initialize_database"
"active_record.log_runtime"
"active_record.set_dispatch_hooks"
"active_record.add_concurrency_middleware"
"action_mailer.logger"
"action_mailer.set_configs"
"active_resource.set_configs"
:set_load_path
:set_autoload_paths
:add_routing_paths
:add_routing_namespaces
:add_locales
:add_view_paths
:load_config_initializers
:engines_blank_point
"my_engine.interact_with_routes"
SUPER
:set_load_path
:set_autoload_paths
:add_routing_paths
:add_routing_namespaces
:add_locales
:add_view_paths
:load_config_initializers
:engines_blank_point
FINISHER
:add_generator_templates
:ensure_autoload_once_paths_as_subset
:add_to_prepare_blocks
:add_builtin_route
:build_middleware_stack
:eager_load!
:finisher_hook
:disable_dependency_loading

Pretty cool stuff. You can see what order things initialize when a Rails server (or console or test) starts up.

I figured I would load my initializer last, to make sure that everything was available in the Application object, so here is my code:

require "my_engine"
require "rails"

module MyEngine
  class Engine < Rails::Engine
      initializer 'my_engine.interact_with_routes', :after=> :disable_dependency_loading do |app|
        # meat goes here
      end
  end
end

I ran a quick test and now my code can see all the routes in my plugin and my rails app. Hopefully this list will be useful when trying to figure out where to place your initializer. Holla!

UPDATE: upon closer inspection it appears that the initializer that loads the routes is :build_middleware_stack inside the finisher.. so putting your route dependant initializer after that initializer should suffice.