aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/dependencies.rb
blob: 5a3dd48f89c5bd5bb1cdab6dc118a2ccea17a49a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
unless Object.respond_to?(:require_dependency)
  Object.send(:define_method, :require_dependency) { |file_name| ActionController::Base.require_dependency(file_name) }
end

module ActionController #:nodoc:
  module Dependencies #:nodoc:
    def self.append_features(base)
      super

      base.class_eval do
        # When turned on (which is default), all dependencies are included using "load". This mean that any change is instant in cached
        # environments like mod_ruby or FastCGI. When set to false, "require" is used, which is faster but requires server restart to
        # be effective.
        @@reload_dependencies = true
        cattr_accessor :reload_dependencies
      end

      base.extend(ClassMethods)
    end

    module ClassMethods
      # Loads the <tt>file_name</tt> if reload_dependencies is true or requires if it's false.
      def require_dependency(file_name)
        reload_dependencies ? silence_warnings { load("#{file_name}.rb") } : require(file_name)
      end
      
      def model(*models)
        require_dependencies(:model, models)
        depend_on(:model, models)
      end

      def service(*services)
        require_dependencies(:service, services)
        depend_on(:service, services)
      end
      
      def observer(*observers)
        require_dependencies(:observer, observers)
        depend_on(:observer, observers)
        instantiate_observers(observers)
      end

      def dependencies_on(layer) # :nodoc:
        read_inheritable_attribute("#{layer}_dependencies")
      end
    
      def depend_on(layer, dependencies)
        write_inheritable_array("#{layer}_dependencies", dependencies)
      end

      private
        def instantiate_observers(observers)
          observers.flatten.each { |observer| Object.const_get(Inflector.classify(observer.to_s)).instance }
        end
        
        def require_dependencies(layer, dependencies)
          dependencies.flatten.each do |dependency|
            begin
              require_dependency(dependency.to_s)
            rescue LoadError
              raise LoadError, "Missing #{layer} #{dependency}.rb"
            end
          end
        end
    end
  end
end