railtie.rb 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. require 'rails/initializable'
  2. require 'rails/configuration'
  3. require 'active_support/inflector'
  4. require 'active_support/core_ext/module/introspection'
  5. require 'active_support/core_ext/module/delegation'
  6. module Rails
  7. # Railtie is the core of the Rails framework and provides several hooks to extend
  8. # Rails and/or modify the initialization process.
  9. #
  10. # Every major component of Rails (Action Mailer, Action Controller,
  11. # Action View, Active Record and Active Resource) is a Railtie. Each of
  12. # them is responsible for their own initialization. This makes Rails itself
  13. # absent of any component hooks, allowing other components to be used in
  14. # place of any of the Rails defaults.
  15. #
  16. # Developing a Rails extension does _not_ require any implementation of
  17. # Railtie, but if you need to interact with the Rails framework during
  18. # or after boot, then Railtie is needed.
  19. #
  20. # For example, an extension doing any of the following would require Railtie:
  21. #
  22. # * creating initializers
  23. # * configuring a Rails framework for the application, like setting a generator
  24. # * adding config.* keys to the environment
  25. # * setting up a subscriber with ActiveSupport::Notifications
  26. # * adding rake tasks
  27. #
  28. # == Creating your Railtie
  29. #
  30. # To extend Rails using Railtie, create a Railtie class which inherits
  31. # from Rails::Railtie within your extension's namespace. This class must be
  32. # loaded during the Rails boot process.
  33. #
  34. # The following example demonstrates an extension which can be used with or without Rails.
  35. #
  36. # # lib/my_gem/railtie.rb
  37. # module MyGem
  38. # class Railtie < Rails::Railtie
  39. # end
  40. # end
  41. #
  42. # # lib/my_gem.rb
  43. # require 'my_gem/railtie' if defined?(Rails)
  44. #
  45. # == Initializers
  46. #
  47. # To add an initialization step from your Railtie to Rails boot process, you just need
  48. # to create an initializer block:
  49. #
  50. # class MyRailtie < Rails::Railtie
  51. # initializer "my_railtie.configure_rails_initialization" do
  52. # # some initialization behavior
  53. # end
  54. # end
  55. #
  56. # If specified, the block can also receive the application object, in case you
  57. # need to access some application specific configuration, like middleware:
  58. #
  59. # class MyRailtie < Rails::Railtie
  60. # initializer "my_railtie.configure_rails_initialization" do |app|
  61. # app.middleware.use MyRailtie::Middleware
  62. # end
  63. # end
  64. #
  65. # Finally, you can also pass :before and :after as option to initializer, in case
  66. # you want to couple it with a specific step in the initialization process.
  67. #
  68. # == Configuration
  69. #
  70. # Inside the Railtie class, you can access a config object which contains configuration
  71. # shared by all railties and the application:
  72. #
  73. # class MyRailtie < Rails::Railtie
  74. # # Customize the ORM
  75. # config.app_generators.orm :my_railtie_orm
  76. #
  77. # # Add a to_prepare block which is executed once in production
  78. # # and before each request in development
  79. # config.to_prepare do
  80. # MyRailtie.setup!
  81. # end
  82. # end
  83. #
  84. # == Loading rake tasks and generators
  85. #
  86. # If your railtie has rake tasks, you can tell Rails to load them through the method
  87. # rake_tasks:
  88. #
  89. # class MyRailtie < Rails::Railtie
  90. # rake_tasks do
  91. # load "path/to/my_railtie.tasks"
  92. # end
  93. # end
  94. #
  95. # By default, Rails load generators from your load path. However, if you want to place
  96. # your generators at a different location, you can specify in your Railtie a block which
  97. # will load them during normal generators lookup:
  98. #
  99. # class MyRailtie < Rails::Railtie
  100. # generators do
  101. # require "path/to/my_railtie_generator"
  102. # end
  103. # end
  104. #
  105. # == Application, Plugin and Engine
  106. #
  107. # A Rails::Engine is nothing more than a Railtie with some initializers already set.
  108. # And since Rails::Application and Rails::Plugin are engines, the same configuration
  109. # described here can be used in all three.
  110. #
  111. # Be sure to look at the documentation of those specific classes for more information.
  112. #
  113. class Railtie
  114. autoload :Configurable, "rails/railtie/configurable"
  115. autoload :Configuration, "rails/railtie/configuration"
  116. include Initializable
  117. ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Plugin Rails::Engine Rails::Application)
  118. class << self
  119. private :new
  120. def subclasses
  121. @subclasses ||= []
  122. end
  123. def inherited(base)
  124. unless base.abstract_railtie?
  125. base.send(:include, Railtie::Configurable)
  126. subclasses << base
  127. end
  128. end
  129. def rake_tasks(&blk)
  130. @rake_tasks ||= []
  131. @rake_tasks << blk if blk
  132. @rake_tasks
  133. end
  134. def console(&blk)
  135. @load_console ||= []
  136. @load_console << blk if blk
  137. @load_console
  138. end
  139. def generators(&blk)
  140. @generators ||= []
  141. @generators << blk if blk
  142. @generators
  143. end
  144. def abstract_railtie?
  145. ABSTRACT_RAILTIES.include?(name)
  146. end
  147. def railtie_name(name = nil)
  148. @railtie_name = name.to_s if name
  149. @railtie_name ||= generate_railtie_name(self.name)
  150. end
  151. protected
  152. def generate_railtie_name(class_or_module)
  153. ActiveSupport::Inflector.underscore(class_or_module).gsub("/", "_")
  154. end
  155. end
  156. delegate :railtie_name, :to => "self.class"
  157. def config
  158. @config ||= Railtie::Configuration.new
  159. end
  160. def eager_load!
  161. end
  162. def load_console(app=self)
  163. self.class.console.each { |block| block.call(app) }
  164. end
  165. def load_tasks(app=self)
  166. extend Rake::DSL if defined? Rake::DSL
  167. self.class.rake_tasks.each { |block| self.instance_exec(app, &block) }
  168. # load also tasks from all superclasses
  169. klass = self.class.superclass
  170. while klass.respond_to?(:rake_tasks)
  171. klass.rake_tasks.each { |t| self.instance_exec(app, &t) }
  172. klass = klass.superclass
  173. end
  174. end
  175. def load_generators(app=self)
  176. self.class.generators.each { |block| block.call(app) }
  177. end
  178. def railtie_namespace
  179. @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) }
  180. end
  181. end
  182. end