engine.rb 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. require 'rails/railtie'
  2. require 'active_support/core_ext/module/delegation'
  3. require 'pathname'
  4. require 'rbconfig'
  5. require 'rails/engine/railties'
  6. module Rails
  7. # <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of
  8. # functionality and share it with other applications. Since Rails 3.0, every
  9. # <tt>Rails::Application</tt> is just an engine, which allows for simple
  10. # feature and application sharing.
  11. #
  12. # Any <tt>Rails::Engine</tt> is also a <tt>Rails::Railtie</tt>, so the same
  13. # methods (like <tt>rake_tasks</tt> and +generators+) and configuration
  14. # options that are available in railties can also be used in engines.
  15. #
  16. # == Creating an Engine
  17. #
  18. # In Rails versions prior to 3.0, your gems automatically behaved as engines, however,
  19. # this coupled Rails to Rubygems. Since Rails 3.0, if you want a gem to automatically
  20. # behave as an engine, you have to specify an +Engine+ for it somewhere inside
  21. # your plugin's +lib+ folder (similar to how we specify a +Railtie+):
  22. #
  23. # # lib/my_engine.rb
  24. # module MyEngine
  25. # class Engine < Rails::Engine
  26. # end
  27. # end
  28. #
  29. # Then ensure that this file is loaded at the top of your <tt>config/application.rb</tt>
  30. # (or in your +Gemfile+) and it will automatically load models, controllers and helpers
  31. # inside +app+, load routes at <tt>config/routes.rb</tt>, load locales at
  32. # <tt>config/locales/*</tt>, and load tasks at <tt>lib/tasks/*</tt>.
  33. #
  34. # == Configuration
  35. #
  36. # Besides the +Railtie+ configuration which is shared across the application, in a
  37. # <tt>Rails::Engine</tt> you can access <tt>autoload_paths</tt>, <tt>eager_load_paths</tt>
  38. # and <tt>autoload_once_paths</tt>, which, differently from a <tt>Railtie</tt>, are scoped to
  39. # the current engine.
  40. #
  41. # Example:
  42. #
  43. # class MyEngine < Rails::Engine
  44. # # Add a load path for this specific Engine
  45. # config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
  46. #
  47. # initializer "my_engine.add_middleware" do |app|
  48. # app.middleware.use MyEngine::Middleware
  49. # end
  50. # end
  51. #
  52. # == Generators
  53. #
  54. # You can set up generators for engines with <tt>config.generators</tt> method:
  55. #
  56. # class MyEngine < Rails::Engine
  57. # config.generators do |g|
  58. # g.orm :active_record
  59. # g.template_engine :erb
  60. # g.test_framework :test_unit
  61. # end
  62. # end
  63. #
  64. # You can also set generators for an application by using <tt>config.app_generators</tt>:
  65. #
  66. # class MyEngine < Rails::Engine
  67. # # note that you can also pass block to app_generators in the same way you
  68. # # can pass it to generators method
  69. # config.app_generators.orm :datamapper
  70. # end
  71. #
  72. # == Paths
  73. #
  74. # Since Rails 3.0, applications and engines have more flexible path configuration (as
  75. # opposed to the previous hardcoded path configuration). This means that you are not
  76. # required to place your controllers at <tt>app/controllers</tt>, but in any place
  77. # which you find convenient.
  78. #
  79. # For example, let's suppose you want to place your controllers in <tt>lib/controllers</tt>.
  80. # You can set that as an option:
  81. #
  82. # class MyEngine < Rails::Engine
  83. # paths["app/controllers"] = "lib/controllers"
  84. # end
  85. #
  86. # You can also have your controllers loaded from both <tt>app/controllers</tt> and
  87. # <tt>lib/controllers</tt>:
  88. #
  89. # class MyEngine < Rails::Engine
  90. # paths["app/controllers"] << "lib/controllers"
  91. # end
  92. #
  93. # The available paths in an engine are:
  94. #
  95. # class MyEngine < Rails::Engine
  96. # paths["app"] # => ["app"]
  97. # paths["app/controllers"] # => ["app/controllers"]
  98. # paths["app/helpers"] # => ["app/helpers"]
  99. # paths["app/models"] # => ["app/models"]
  100. # paths["app/views"] # => ["app/views"]
  101. # paths["lib"] # => ["lib"]
  102. # paths["lib/tasks"] # => ["lib/tasks"]
  103. # paths["config"] # => ["config"]
  104. # paths["config/initializers"] # => ["config/initializers"]
  105. # paths["config/locales"] # => ["config/locales"]
  106. # paths["config/routes"] # => ["config/routes.rb"]
  107. # end
  108. #
  109. # The <tt>Application</tt> class adds a couple more paths to this set. And as in your
  110. # <tt>Application</tt>, all folders under +app+ are automatically added to the load path.
  111. # If you have an <tt>app/observers</tt> folder for example, it will be added by default.
  112. #
  113. # == Endpoint
  114. #
  115. # An engine can be also a rack application. It can be useful if you have a rack application that
  116. # you would like to wrap with +Engine+ and provide some of the +Engine+'s features.
  117. #
  118. # To do that, use the +endpoint+ method:
  119. #
  120. # module MyEngine
  121. # class Engine < Rails::Engine
  122. # endpoint MyRackApplication
  123. # end
  124. # end
  125. #
  126. # Now you can mount your engine in application's routes just like that:
  127. #
  128. # MyRailsApp::Application.routes.draw do
  129. # mount MyEngine::Engine => "/engine"
  130. # end
  131. #
  132. # == Middleware stack
  133. #
  134. # As an engine can now be a rack endpoint, it can also have a middleware
  135. # stack. The usage is exactly the same as in <tt>Application</tt>:
  136. #
  137. # module MyEngine
  138. # class Engine < Rails::Engine
  139. # middleware.use SomeMiddleware
  140. # end
  141. # end
  142. #
  143. # == Routes
  144. #
  145. # If you don't specify an endpoint, routes will be used as the default
  146. # endpoint. You can use them just like you use an application's routes:
  147. #
  148. # # ENGINE/config/routes.rb
  149. # MyEngine::Engine.routes.draw do
  150. # match "/" => "posts#index"
  151. # end
  152. #
  153. # == Mount priority
  154. #
  155. # Note that now there can be more than one router in your application, and it's better to avoid
  156. # passing requests through many routers. Consider this situation:
  157. #
  158. # MyRailsApp::Application.routes.draw do
  159. # mount MyEngine::Engine => "/blog"
  160. # match "/blog/omg" => "main#omg"
  161. # end
  162. #
  163. # +MyEngine+ is mounted at <tt>/blog</tt>, and <tt>/blog/omg</tt> points to application's
  164. # controller. In such a situation, requests to <tt>/blog/omg</tt> will go through +MyEngine+,
  165. # and if there is no such route in +Engine+'s routes, it will be dispatched to <tt>main#omg</tt>.
  166. # It's much better to swap that:
  167. #
  168. # MyRailsApp::Application.routes.draw do
  169. # match "/blog/omg" => "main#omg"
  170. # mount MyEngine::Engine => "/blog"
  171. # end
  172. #
  173. # Now, +Engine+ will get only requests that were not handled by +Application+.
  174. #
  175. # == Engine name
  176. #
  177. # There are some places where an Engine's name is used:
  178. #
  179. # * routes: when you mount an Engine with <tt>mount(MyEngine::Engine => '/my_engine')</tt>,
  180. # it's used as default :as option
  181. # * some of the rake tasks are based on engine name, e.g. <tt>my_engine:install:migrations</tt>,
  182. # <tt>my_engine:install:assets</tt>
  183. #
  184. # Engine name is set by default based on class name. For <tt>MyEngine::Engine</tt> it will be
  185. # <tt>my_engine_engine</tt>. You can change it manually using the <tt>engine_name</tt> method:
  186. #
  187. # module MyEngine
  188. # class Engine < Rails::Engine
  189. # engine_name "my_engine"
  190. # end
  191. # end
  192. #
  193. # == Isolated Engine
  194. #
  195. # Normally when you create controllers, helpers and models inside an engine, they are treated
  196. # as if they were created inside the application itself. This means that all helpers and
  197. # named routes from the application will be available to your engine's controllers as well.
  198. #
  199. # However, sometimes you want to isolate your engine from the application, especially if your engine
  200. # has its own router. To do that, you simply need to call +isolate_namespace+. This method requires
  201. # you to pass a module where all your controllers, helpers and models should be nested to:
  202. #
  203. # module MyEngine
  204. # class Engine < Rails::Engine
  205. # isolate_namespace MyEngine
  206. # end
  207. # end
  208. #
  209. # With such an engine, everything that is inside the +MyEngine+ module will be isolated from
  210. # the application.
  211. #
  212. # Consider such controller:
  213. #
  214. # module MyEngine
  215. # class FooController < ActionController::Base
  216. # end
  217. # end
  218. #
  219. # If an engine is marked as isolated, +FooController+ has access only to helpers from +Engine+ and
  220. # <tt>url_helpers</tt> from <tt>MyEngine::Engine.routes</tt>.
  221. #
  222. # The next thing that changes in isolated engines is the behavior of routes. Normally, when you namespace
  223. # your controllers, you also need to do namespace all your routes. With an isolated engine,
  224. # the namespace is applied by default, so you can ignore it in routes:
  225. #
  226. # MyEngine::Engine.routes.draw do
  227. # resources :articles
  228. # end
  229. #
  230. # The routes above will automatically point to <tt>MyEngine::ApplicationController</tt>. Furthermore, you don't
  231. # need to use longer url helpers like <tt>my_engine_articles_path</tt>. Instead, you should simply use
  232. # <tt>articles_path</tt> as you would do with your application.
  233. #
  234. # To make that behavior consistent with other parts of the framework, an isolated engine also has influence on
  235. # <tt>ActiveModel::Naming</tt>. When you use a namespaced model, like <tt>MyEngine::Article</tt>, it will normally
  236. # use the prefix "my_engine". In an isolated engine, the prefix will be omitted in url helpers and
  237. # form fields for convenience.
  238. #
  239. # polymorphic_url(MyEngine::Article.new) # => "articles_path"
  240. #
  241. # form_for(MyEngine::Article.new) do
  242. # text_field :title # => <input type="text" name="article[title]" id="article_title" />
  243. # end
  244. #
  245. # Additionally, an isolated engine will set its name according to namespace, so
  246. # MyEngine::Engine.engine_name will be "my_engine". It will also set MyEngine.table_name_prefix
  247. # to "my_engine_", changing the MyEngine::Article model to use the my_engine_articles table.
  248. #
  249. # == Using Engine's routes outside Engine
  250. #
  251. # Since you can now mount an engine inside application's routes, you do not have direct access to +Engine+'s
  252. # <tt>url_helpers</tt> inside +Application+. When you mount an engine in an application's routes, a special helper is
  253. # created to allow you to do that. Consider such a scenario:
  254. #
  255. # # config/routes.rb
  256. # MyApplication::Application.routes.draw do
  257. # mount MyEngine::Engine => "/my_engine", :as => "my_engine"
  258. # match "/foo" => "foo#index"
  259. # end
  260. #
  261. # Now, you can use the <tt>my_engine</tt> helper inside your application:
  262. #
  263. # class FooController < ApplicationController
  264. # def index
  265. # my_engine.root_url #=> /my_engine/
  266. # end
  267. # end
  268. #
  269. # There is also a <tt>main_app</tt> helper that gives you access to application's routes inside Engine:
  270. #
  271. # module MyEngine
  272. # class BarController
  273. # def index
  274. # main_app.foo_path #=> /foo
  275. # end
  276. # end
  277. # end
  278. #
  279. # Note that the <tt>:as</tt> option given to mount takes the <tt>engine_name</tt> as default, so most of the time
  280. # you can simply omit it.
  281. #
  282. # Finally, if you want to generate a url to an engine's route using
  283. # <tt>polymorphic_url</tt>, you also need to pass the engine helper. Let's
  284. # say that you want to create a form pointing to one of the engine's routes.
  285. # All you need to do is pass the helper as the first element in array with
  286. # attributes for url:
  287. #
  288. # form_for([my_engine, @user])
  289. #
  290. # This code will use <tt>my_engine.user_path(@user)</tt> to generate the proper route.
  291. #
  292. # == Isolated engine's helpers
  293. #
  294. # Sometimes you may want to isolate engine, but use helpers that are defined for it.
  295. # If you want to share just a few specific helpers you can add them to application's
  296. # helpers in ApplicationController:
  297. #
  298. # class ApplicationController < ActionController::Base
  299. # helper MyEngine::SharedEngineHelper
  300. # end
  301. #
  302. # If you want to include all of the engine's helpers, you can use #helpers method on an engine's
  303. # instance:
  304. #
  305. # class ApplicationController < ActionController::Base
  306. # helper MyEngine::Engine.helpers
  307. # end
  308. #
  309. # It will include all of the helpers from engine's directory. Take into account that this does
  310. # not include helpers defined in controllers with helper_method or other similar solutions,
  311. # only helpers defined in the helpers directory will be included.
  312. #
  313. # == Migrations & seed data
  314. #
  315. # Engines can have their own migrations. The default path for migrations is exactly the same
  316. # as in application: <tt>db/migrate</tt>
  317. #
  318. # To use engine's migrations in application you can use rake task, which copies them to
  319. # application's dir:
  320. #
  321. # rake ENGINE_NAME:install:migrations
  322. #
  323. # Note that some of the migrations may be skipped if a migration with the same name already exists
  324. # in application. In such a situation you must decide whether to leave that migration or rename the
  325. # migration in the application and rerun copying migrations.
  326. #
  327. # If your engine has migrations, you may also want to prepare data for the database in
  328. # the <tt>seeds.rb</tt> file. You can load that data using the <tt>load_seed</tt> method, e.g.
  329. #
  330. # MyEngine::Engine.load_seed
  331. #
  332. # == Loading priority
  333. #
  334. # In order to change engine's priority you can use config.railties_order in main application.
  335. # It will affect the priority of loading views, helpers, assets and all the other files
  336. # related to engine or application.
  337. #
  338. # Example:
  339. #
  340. # # load Blog::Engine with highest priority, followed by application and other railties
  341. # config.railties_order = [Blog::Engine, :main_app, :all]
  342. #
  343. class Engine < Railtie
  344. autoload :Configuration, "rails/engine/configuration"
  345. autoload :Railties, "rails/engine/railties"
  346. def load_generators(app=self)
  347. initialize_generators
  348. railties.all { |r| r.load_generators(app) }
  349. Rails::Generators.configure!(app.config.generators)
  350. super
  351. self
  352. end
  353. class << self
  354. attr_accessor :called_from, :isolated
  355. alias :isolated? :isolated
  356. alias :engine_name :railtie_name
  357. def inherited(base)
  358. unless base.abstract_railtie?
  359. base.called_from = begin
  360. # Remove the line number from backtraces making sure we don't leave anything behind
  361. call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
  362. File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
  363. end
  364. end
  365. super
  366. end
  367. def endpoint(endpoint = nil)
  368. @endpoint ||= nil
  369. @endpoint = endpoint if endpoint
  370. @endpoint
  371. end
  372. def isolate_namespace(mod)
  373. engine_name(generate_railtie_name(mod))
  374. self.routes.default_scope = { :module => ActiveSupport::Inflector.underscore(mod.name) }
  375. self.isolated = true
  376. unless mod.respond_to?(:railtie_namespace)
  377. name, railtie = engine_name, self
  378. mod.singleton_class.instance_eval do
  379. define_method(:railtie_namespace) { railtie }
  380. unless mod.respond_to?(:table_name_prefix)
  381. define_method(:table_name_prefix) { "#{name}_" }
  382. end
  383. unless mod.respond_to?(:use_relative_model_naming?)
  384. class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__
  385. end
  386. unless mod.respond_to?(:railtie_helpers_paths)
  387. define_method(:railtie_helpers_paths) { railtie.helpers_paths }
  388. end
  389. unless mod.respond_to?(:railtie_routes_url_helpers)
  390. define_method(:railtie_routes_url_helpers) { railtie.routes_url_helpers }
  391. end
  392. end
  393. end
  394. end
  395. # Finds engine with given path
  396. def find(path)
  397. expanded_path = File.expand_path path.to_s
  398. Rails::Engine::Railties.engines.find { |engine|
  399. File.expand_path(engine.root.to_s) == expanded_path
  400. }
  401. end
  402. end
  403. delegate :middleware, :root, :paths, :to => :config
  404. delegate :engine_name, :isolated?, :to => "self.class"
  405. def load_tasks(app=self)
  406. railties.all { |r| r.load_tasks(app) }
  407. super
  408. paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
  409. end
  410. def load_console(app=self)
  411. railties.all { |r| r.load_console(app) }
  412. super
  413. end
  414. def eager_load!
  415. railties.all(&:eager_load!)
  416. config.eager_load_paths.each do |load_path|
  417. matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
  418. Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
  419. require_dependency file.sub(matcher, '\1')
  420. end
  421. end
  422. end
  423. def railties
  424. @railties ||= self.class::Railties.new(config)
  425. end
  426. def helpers
  427. @helpers ||= begin
  428. helpers = Module.new
  429. all = ActionController::Base.all_helpers_from_path(helpers_paths)
  430. ActionController::Base.modules_for_helpers(all).each do |mod|
  431. helpers.send(:include, mod)
  432. end
  433. helpers
  434. end
  435. end
  436. def helpers_paths
  437. paths["app/helpers"].existent
  438. end
  439. def routes_url_helpers
  440. routes.url_helpers
  441. end
  442. def app
  443. @app ||= begin
  444. config.middleware = config.middleware.merge_into(default_middleware_stack)
  445. config.middleware.build(endpoint)
  446. end
  447. end
  448. def endpoint
  449. self.class.endpoint || routes
  450. end
  451. def call(env)
  452. app.call(env.merge!(env_config))
  453. end
  454. def env_config
  455. @env_config ||= {
  456. 'action_dispatch.routes' => routes
  457. }
  458. end
  459. def routes
  460. @routes ||= ActionDispatch::Routing::RouteSet.new
  461. @routes.append(&Proc.new) if block_given?
  462. @routes
  463. end
  464. def ordered_railties
  465. railties.all + [self]
  466. end
  467. def initializers
  468. initializers = []
  469. ordered_railties.each do |r|
  470. if r == self
  471. initializers += super
  472. else
  473. initializers += r.initializers
  474. end
  475. end
  476. initializers
  477. end
  478. def config
  479. @config ||= Engine::Configuration.new(find_root_with_flag("lib"))
  480. end
  481. # Load data from db/seeds.rb file. It can be used in to load engines'
  482. # seeds, e.g.:
  483. #
  484. # Blog::Engine.load_seed
  485. def load_seed
  486. seed_file = paths["db/seeds"].existent.first
  487. load(seed_file) if seed_file
  488. end
  489. # Add configured load paths to ruby load paths and remove duplicates.
  490. initializer :set_load_path, :before => :bootstrap_hook do
  491. _all_load_paths.reverse_each do |path|
  492. $LOAD_PATH.unshift(path) if File.directory?(path)
  493. end
  494. $LOAD_PATH.uniq!
  495. end
  496. # Set the paths from which Rails will automatically load source files,
  497. # and the load_once paths.
  498. #
  499. # This needs to be an initializer, since it needs to run once
  500. # per engine and get the engine as a block parameter
  501. initializer :set_autoload_paths, :before => :bootstrap_hook do |app|
  502. ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
  503. ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths)
  504. # Freeze so future modifications will fail rather than do nothing mysteriously
  505. config.autoload_paths.freeze
  506. config.eager_load_paths.freeze
  507. config.autoload_once_paths.freeze
  508. end
  509. initializer :add_routing_paths do |app|
  510. paths = self.paths["config/routes"].existent
  511. if routes? || paths.any?
  512. app.routes_reloader.paths.unshift(*paths)
  513. app.routes_reloader.route_sets << routes
  514. end
  515. end
  516. # I18n load paths are a special case since the ones added
  517. # later have higher priority.
  518. initializer :add_locales do
  519. config.i18n.railties_load_path.concat(paths["config/locales"].existent)
  520. end
  521. initializer :add_view_paths do
  522. views = paths["app/views"].existent
  523. unless views.empty?
  524. ActiveSupport.on_load(:action_controller){ prepend_view_path(views) }
  525. ActiveSupport.on_load(:action_mailer){ prepend_view_path(views) }
  526. end
  527. end
  528. initializer :load_environment_config, :before => :load_environment_hook, :group => :all do
  529. environment = paths["config/environments"].existent.first
  530. require environment if environment
  531. end
  532. initializer :append_assets_path, :group => :all do |app|
  533. app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
  534. app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
  535. app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
  536. end
  537. initializer :prepend_helpers_path do |app|
  538. if !isolated? || (app == self)
  539. app.config.helpers_paths.unshift(*paths["app/helpers"].existent)
  540. end
  541. end
  542. initializer :load_config_initializers do
  543. config.paths["config/initializers"].existent.sort.each do |initializer|
  544. load(initializer)
  545. end
  546. end
  547. initializer :engines_blank_point do
  548. # We need this initializer so all extra initializers added in engines are
  549. # consistently executed after all the initializers above across all engines.
  550. end
  551. rake_tasks do
  552. next if self.is_a?(Rails::Application)
  553. next unless has_migrations?
  554. namespace railtie_name do
  555. namespace :install do
  556. desc "Copy migrations from #{railtie_name} to application"
  557. task :migrations do
  558. ENV["FROM"] = railtie_name
  559. Rake::Task["railties:install:migrations"].invoke
  560. end
  561. end
  562. end
  563. end
  564. protected
  565. def initialize_generators
  566. require "rails/generators"
  567. end
  568. def routes?
  569. defined?(@routes)
  570. end
  571. def has_migrations?
  572. paths["db/migrate"].existent.any?
  573. end
  574. def find_root_with_flag(flag, default=nil)
  575. root_path = self.class.called_from
  576. while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
  577. parent = File.dirname(root_path)
  578. root_path = parent != root_path && parent
  579. end
  580. root = File.exist?("#{root_path}/#{flag}") ? root_path : default
  581. raise "Could not find root path for #{self}" unless root
  582. RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ?
  583. Pathname.new(root).expand_path : Pathname.new(root).realpath
  584. end
  585. def default_middleware_stack
  586. ActionDispatch::MiddlewareStack.new
  587. end
  588. def _all_autoload_once_paths
  589. config.autoload_once_paths
  590. end
  591. def _all_autoload_paths
  592. @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
  593. end
  594. def _all_load_paths
  595. @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
  596. end
  597. end
  598. end