diff options
Diffstat (limited to 'railties/lib')
-rw-r--r-- | railties/lib/rails/application.rb | 7 | ||||
-rw-r--r-- | railties/lib/rails/application/routes_reloader.rb | 24 | ||||
-rw-r--r-- | railties/lib/rails/engine.rb | 120 | ||||
-rw-r--r-- | railties/lib/rails/generators/actions.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/plugin.rb | 2 | ||||
-rw-r--r-- | railties/lib/rails/railtie.rb | 7 | ||||
-rw-r--r-- | railties/lib/rails/tasks/documentation.rake | 2 | ||||
-rw-r--r-- | railties/lib/rails/tasks/railties.rake | 2 | ||||
-rw-r--r-- | railties/lib/rails/test_unit/testing.rake | 7 |
9 files changed, 100 insertions, 75 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 5559f49fbd..d13356ab4d 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -128,10 +128,9 @@ module Rails end def initializers - initializers = Bootstrap.initializers_for(self) - initializers += super - initializers += Finisher.initializers_for(self) - initializers + Bootstrap.initializers_for(self) + + super + + Finisher.initializers_for(self) end def config diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb index 6da903c1ac..1d1f5e1b06 100644 --- a/railties/lib/rails/application/routes_reloader.rb +++ b/railties/lib/rails/application/routes_reloader.rb @@ -1,17 +1,15 @@ module Rails class Application class RoutesReloader < ::ActiveSupport::FileUpdateChecker + attr_reader :route_sets + def initialize super([]) { reload! } - end - - def blocks - @blocks ||= {} + @route_sets = [] end def reload! clear! - load_blocks load_paths finalize! ensure @@ -21,37 +19,27 @@ module Rails protected def clear! - routers.each do |routes| + route_sets.each do |routes| routes.disable_clear_and_finalize = true routes.clear! end end - def load_blocks - blocks.each do |routes, block| - routes.draw(&block) if block - end - end - def load_paths paths.each { |path| load(path) } end def finalize! - routers.each do |routes| + route_sets.each do |routes| ActiveSupport.on_load(:action_controller) { routes.finalize! } end end def revert - routers.each do |routes| + route_sets.each do |routes| routes.disable_clear_and_finalize = false end end - - def routers - blocks.keys - end end end end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 1aa24b6808..e9ce9610b8 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -77,14 +77,14 @@ module Rails # you need to do is: # # class MyEngine < Rails::Engine - # paths.app.controllers = "lib/controllers" + # paths["app/controllers"] = "lib/controllers" # end # # You can also have your controllers being loaded from both "app/controllers" and # "lib/controllers": # # class MyEngine < Rails::Engine - # paths.app.controllers << "lib/controllers" + # paths["app/controllers"] << "lib/controllers" # end # # The available paths in an Engine are: @@ -185,19 +185,21 @@ module Rails # == Serving static files # # By default, rails use ActionDispatch::Static to serve static files in development mode. This is ok - # while you develop your application, but when you want to deploy it, assets from engine will not be served. + # while you develop your application, but when you want to deploy it, assets from engine will not be + # served by default. You should choose one of the two following strategies: # - # You can fix it in one of two ways: # * enable serving static files by setting config.serve_static_assets to true # * symlink engines' public directories in application's public directory by running - # `rake railties:create_symlinks` + # `rake ENGINE_NAME:install:assets`, where ENGINE_NAME is usually my_engine for the + # examples above # # == Engine name # # There are some places where engine's name is used. + # # * routes: when you mount engine with mount(MyEngine::Engine => '/my_engine'), it's used as default :as option - # * migrations: when you copy engine's migrations, they will be decorated with suffix based on engine_name, for example: - # 2010010203121314_create_users.my_engine.rb + # + # * rake tasks: engines have a few rake tasks. They are usually under my_engine namespace. # # Engine name is set by default based on class name. For MyEngine::Engine it will be my_engine_engine. # You can change it manually it manually using engine_name method: @@ -210,15 +212,17 @@ module Rails # # == Namespaced Engine # - # Normally, when you create controllers, helpers and models inside engine, they are treated - # as they would be created inside application. One of the cosequences of that is including - # application's helpers and url_helpers inside controller. Sometimes, especially when your - # engine provides its own routes, you don't want that. To isolate engine's stuff from application - # you can use namespace method: + # Normally when you create controllers, helpers and models inside engine, they are treated + # as they were created inside the application. This means all applications helpers and named routes + # will be available to your engine controllers. + # + # However, sometimes you want to isolate your engine from the application, specially if your engine + # have its own router. To do that, you simply need to call +isolate_namespace+. This method requires + # you to pass a module where all your controllers, helpers and models should be nested to: # # module MyEngine # class Engine < Rails::Engine - # namespace MyEngine + # isolate_namespace MyEngine # end # end # @@ -235,15 +239,21 @@ module Rails # url_helpers from MyEngine::Engine.routes. # # The next thing that changes in isolated engine is routes behaviour. Normally, when you namespace - # your controllers, you need to use scope or namespace method in routes. With isolated engine, - # the namespace is applied by default, so you can ignore it in routes. Further more, you don't need - # to use longer url helpers like "my_engine_articles_path". As the prefix is not set you can just use - # articles_path as you would normally do. + # your controllers, you also need to do namespace all your routes. With isolated engine, + # the namespace is applied by default, so you can ignore it in routes: + # + # MyEngine::Engine.routes.draw do + # resources :articles + # end + # + # The routes above will automatically point to MyEngine::ApplicationContoller. Further more, you don't + # need to use longer url helpers like "my_engine_articles_path". Instead, you shuold simply use + # articles_path as you would do with your application. # # To make that behaviour consistent with other parts of framework, isolated engine has influence also on # ActiveModel::Naming. When you use namespaced model, like MyEngine::Article, it will normally - # use the prefix "my_engine". In isolated engine, the prefix will be ommited in most of the places, - # like url helpers or form fields. + # use the prefix "my_engine". In isolated engine, the prefix will be ommited in url helpers and + # form fields for convenience. # # polymorphic_url(MyEngine::Article.new) #=> "articles_path" # @@ -251,16 +261,15 @@ module Rails # text_field :title #=> <input type="text" name="article[title]" id="article_title" /> # end # - # - # Additionaly namespaced engine will set its name according to namespace, so in that case: - # MyEngine::Engine.engine_name #=> "my_engine" and it will set MyEngine.table_name_prefix - # to "my_engine_". + # Additionaly isolated engine will set its name according to namespace, so + # MyEngine::Engine.engine_name #=> "my_engine". It will also set MyEngine.table_name_prefix + # to "my_engine_", changing MyEngine::Article model to use my_engine_article table. # # == Using Engine's routes outside Engine # - # Since you can mount engine inside application's routes now, you do not have direct access to engine's - # url_helpers inside application. When you mount Engine in application's routes special helper is - # created to allow doing that. Consider such scenario: + # Since now you can mount engine inside application's routes, you do not have direct access to engine's + # url_helpers inside application. When you mount Engine in application's routes, a special helper is + # created to allow you to do that. Consider such scenario: # # # APP/config/routes.rb # MyApplication::Application.routes.draw do @@ -268,7 +277,7 @@ module Rails # match "/foo" => "foo#index" # end # - # Now, you can use my_engine helper: + # Now, you can use my_engine helper inside your application: # # class FooController < ApplicationController # def index @@ -280,20 +289,23 @@ module Rails # # module MyEngine # class BarController - # main_app.foo_path #=> /foo + # def index + # main_app.foo_path #=> /foo + # end # end # end # - # Note that :as option takes engine_name as default, so most of the time you can ommit it. + # Note that the :as option given to mount takes the engine_name as default, so most of the time + # you can simply ommit it. # - # If you want to generate url to engine's route using polymorphic_url, you can also use that helpers. - # - # Let's say that you want to create a form pointing to one of the engine's routes. All you need to do - # is passing helper as the first element in array with attributes for url: + # Finally, if you want to generate url to engine's route using polymorphic_url, you also need + # to pass the engine helper. Let's say that you want to create a form pointing to one of the + # engine's routes. All you need to do is pass the helper as the first element in array with + # attributes for url: # # form_for([my_engine, @user]) # - # This code will use my_engine.user_path(@user) to generate proper route. + # This code will use my_engine.user_path(@user) to generate the proper route. # # == Migrations & seed data # @@ -303,7 +315,7 @@ module Rails # To use engine's migrations in application you can use rake task, which copies them to # application's dir: # - # rake railties:copy_migrations + # rake ENGINE_NAME:install:migrations # # If your engine has migrations, you may also want to prepare data for the database in # seeds.rb file. You can load that data using load_seed method, e.g. @@ -315,7 +327,7 @@ module Rails autoload :Configuration, "rails/engine/configuration" class << self - attr_accessor :called_from, :namespaced + attr_accessor :called_from, :isolated alias :engine_name :railtie_name def inherited(base) @@ -350,12 +362,12 @@ module Rails @endpoint end - def namespace(mod) + def isolate_namespace(mod) engine_name(generate_railtie_name(mod)) name = engine_name self.routes.default_scope = {:module => name} - self.namespaced = true + self.isolated = true unless mod.respond_to?(:_railtie) _railtie = self @@ -371,13 +383,13 @@ module Rails end end - def namespaced? - !!namespaced + def isolated? + !!isolated end end delegate :middleware, :root, :paths, :to => :config - delegate :engine_name, :namespaced?, :to => "self.class" + delegate :engine_name, :isolated?, :to => "self.class" def load_tasks super @@ -419,9 +431,9 @@ module Rails } end - def routes(&block) + def routes @routes ||= ActionDispatch::Routing::RouteSet.new - self.routes_draw_block = block if block_given? + @routes.append(&Proc.new) if block_given? @routes end @@ -472,8 +484,8 @@ module Rails paths = self.paths["config/routes"].existent if routes? || paths.any? - app.routes_reloader.blocks[routes] = routes_draw_block app.routes_reloader.paths.unshift(*paths) + app.routes_reloader.route_sets << routes end end @@ -506,7 +518,7 @@ module Rails end initializer :prepend_helpers_path do |app| - if !namespaced? || (app == self) + if !isolated? || (app == self) app.config.helpers_paths.unshift(*paths["app/helpers"].existent) end end @@ -522,9 +534,23 @@ module Rails # consistently executed after all the initializers above across all engines. end - protected - attr_accessor :routes_draw_block + rake_tasks do + next if self.is_a?(Rails::Application) + + namespace railtie_name do + namespace :install do + # TODO Add assets copying to this list + # TODO Skip this if there is no paths["db/migrate"] for the engine + desc "Copy migrations from #{railtie_name} to application" + task :migrations do + ENV["FROM"] = railtie_name + Rake::Task["railties:install:migrations"].invoke + end + end + end + end + protected def routes? defined?(@routes) end diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 8f0d5ffff4..378c07cb0e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -187,8 +187,8 @@ module Rails # initializer("globals.rb") do # data = "" # - # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do - # data << "#{const} = :entp" + # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do |const| + # data << "#{const} = :entp\n" # end # # data diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb index 76fa76598c..ceddd25eaa 100644 --- a/railties/lib/rails/plugin.rb +++ b/railties/lib/rails/plugin.rb @@ -83,7 +83,7 @@ module Rails initializer :sanity_check_railties_collision do if Engine.subclasses.map { |k| k.root.to_s }.include?(root.to_s) - raise "\"#{name}\" is a Railtie/Engine and cannot be installed as plugin" + raise "\"#{name}\" is a Railtie/Engine and cannot be installed as a plugin" end end end diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb index 2b68a3c453..c76bc83377 100644 --- a/railties/lib/rails/railtie.rb +++ b/railties/lib/rails/railtie.rb @@ -191,6 +191,13 @@ module Rails def load_tasks self.class.rake_tasks.each(&:call) + + # load also tasks from all superclasses + klass = self.class.superclass + while klass.respond_to?(:rake_tasks) + klass.rake_tasks.each { |t| self.instance_exec(&t) } + klass = klass.superclass + end end def load_generators diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake index 7aefbb49b0..edd716d7d0 100644 --- a/railties/lib/rails/tasks/documentation.rake +++ b/railties/lib/rails/tasks/documentation.rake @@ -47,7 +47,7 @@ namespace :doc do rdoc.rdoc_files.include('app/**/*.rb') rdoc.rdoc_files.include('lib/**/*.rb') } - Rake::Task['doc:app'].comment = "Generate docs for the app -- also availble doc:rails, doc:guides, doc:plugins (options: TEMPLATE=/rdoc-template.rb, TITLE=\"Custom Title\")" + Rake::Task['doc:app'].comment = "Generate docs for the app -- also available doc:rails, doc:guides, doc:plugins (options: TEMPLATE=/rdoc-template.rb, TITLE=\"Custom Title\")" # desc 'Generate documentation for the Rails framework.' RDocTaskWithoutDescriptions.new("rails") { |rdoc| diff --git a/railties/lib/rails/tasks/railties.rake b/railties/lib/rails/tasks/railties.rake index 0c1ee0f17a..e08bd9687d 100644 --- a/railties/lib/rails/tasks/railties.rake +++ b/railties/lib/rails/tasks/railties.rake @@ -1,5 +1,5 @@ namespace :railties do - desc "Create symlinks to railties public directories in application's public directory." + # desc "Create symlinks to railties public directories in application's public directory." task :create_symlinks => :environment do paths = Rails.application.config.static_asset_paths.dup app_public_path = Rails.application.paths["public"].first diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index 713833f884..28dc40379b 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -73,7 +73,8 @@ end desc 'Runs test:units, test:functionals, test:integration together (also available: test:benchmark, test:profile, test:plugins)' task :test do - errors = %w(test:units test:functionals test:integration).collect do |task| + tests_to_run = ENV['TEST'] ? ["test:single"] : %w(test:units test:functionals test:integration) + errors = tests_to_run.collect do |task| begin Rake::Task[task].invoke nil @@ -123,6 +124,10 @@ namespace :test do end Rake::Task['test:uncommitted'].comment = "Test changes since last checkin (only Subversion and Git)" + Rake::TestTask.new(:single => "test:prepare") do |t| + t.libs << "test" + end + TestTaskWithoutDescription.new(:units => "test:prepare") do |t| t.libs << "test" t.pattern = 'test/unit/**/*_test.rb' |