9

I want to write a gem that adds a app/services directory to a Rails application.

Since I want to add it from within the Gem i came up with this solution:

class Railtie < ::Rails::Railtie
  config.after_initialize do |app|
    ::Rails.logger.info "adding #{ActiveService::Configuration.path} to autoload_path"
    app.config.autoload_paths = [ActiveService::Configuration.path] + app.config.autoload_paths
  end
end

The problem is that config.autoload_path is a frozen array, so that modifing it seems not to be a good idea.

Any suggestions of how this could be achieved in a better way?

phoet
  • 18,688
  • 4
  • 46
  • 74

2 Answers2

12

config.autoload_paths is frozen inside the :set_autload_paths initializer. The Array is passed on to ActiveSupport::Dependencies.autoload_paths, so modifying the original Array would not make much sense. Therefore it's frozen.

You should be able to hook into :before => :set_autoload_paths and extend config.autoload_paths before it's passed and frozen:

class Railtie < ::Rails::Railtie
  initializer 'activeservice.autoload', :before => :set_autoload_paths do |app|
    app.config.autoload_paths << ActiveService::Configuration.path
  end
end

Documentation about initializer hooks can be found at guides.rubyonrails.org/initialization.html

rubiii
  • 6,903
  • 2
  • 38
  • 51
  • this approach looks promising, but unfortunately it does not work! it looks like the ```app.config``` is different from the config that is used within the engine class. i am currently stuck with using the railtie ```before_configuration``` hook, which can set the autoload_paths array, but runs before all other initializers. so i need to put any configuration into a yml file. – phoet Jun 20 '11 at 19:33
  • didn't know there were engines involved. is there an up-to-date repository to test this out? – rubiii Jun 20 '11 at 20:14
4

First, all directories under app/* are already in the load path since Rails 3.0. In any case, if you want to do it, you should use the paths api instead. Example from Rails source code:

https://github.com/rails/rails/blob/master/railties/lib/rails/engine/configuration.rb#L42

José Valim
  • 50,409
  • 12
  • 130
  • 115
  • you mean like ```app.config.paths.add "lib/services", :eager_load => true``` instead of directly adding it to autoload_paths? my problem is, that this only works in the ```before_configuration``` hook. adding it to the paths in every other initializer ignores the changes and the classes do not get loaded. – phoet Jun 21 '11 at 07:16