require 'initializer' unless defined? Rails::Initializer
class Rails::Initializer #:nodoc:
=begin rdoc
Searches for models that use has_many_polymorphs or acts_as_double_polymorphic_join and makes sure that they get loaded during app initialization. This ensures that helper methods are injected into the target classes.
Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_polymorphs_options. For example, if you need an application extension to be required before has_many_polymorphs loads your models, add an after_initialize block in config/environment.rb that appends to the 'requirements' key:
Rails::Initializer.run do |config|
# your other configuration here
config.after_initialize do
config.has_many_polymorphs_options['requirements'] << '/lib/my_extension'
end
end
=end
module HasManyPolymorphsAutoload
DEFAULT_OPTIONS = {
:file_pattern => "#{RAILS_ROOT}/app/models/**/*.rb",
:file_exclusions => ['svn', 'CVS', 'bzr'],
:methods => ['has_many_polymorphs', 'acts_as_double_polymorphic_join'],
:requirements => []}
mattr_accessor :options
@@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
# Override for Rails::Initializer#after_initialize.
def after_initialize_with_autoload
after_initialize_without_autoload
_logger_debug "autoload hook invoked"
HasManyPolymorphsAutoload.options[:requirements].each do |requirement|
require requirement
end
Dir[HasManyPolymorphsAutoload.options[:file_pattern]].each do |filename|
next if filename =~ /#{HasManyPolymorphsAutoload.options[:file_exclusions].join("|")}/
open filename do |file|
if file.grep(/#{HasManyPolymorphsAutoload.options[:methods].join("|")}/).any?
begin
model = File.basename(filename)[0..-4].camelize
_logger_warn "preloading parent model #{model}"
model.constantize
rescue Object => e
_logger_warn "WARNING; possibly critical error preloading #{model}: #{e.inspect}"
end
end
end
end
end
end
include HasManyPolymorphsAutoload
alias_method_chain :after_initialize, :autoload
end