aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md17
-rw-r--r--railties/guides/code/getting_started/app/views/layouts/application.html.erb2
-rw-r--r--railties/guides/source/active_record_querying.textile16
-rw-r--r--railties/guides/source/active_support_core_extensions.textile39
-rw-r--r--railties/guides/source/configuring.textile2
-rw-r--r--railties/guides/source/getting_started.textile2
-rw-r--r--railties/guides/source/initialization.textile22
-rw-r--r--railties/lib/rails/application.rb31
-rw-r--r--railties/lib/rails/application/configuration.rb5
-rw-r--r--railties/lib/rails/application/route_inspector.rb37
-rw-r--r--railties/lib/rails/code_statistics.rb17
-rw-r--r--railties/lib/rails/commands/dbconsole.rb2
-rw-r--r--railties/lib/rails/engine.rb67
-rw-r--r--railties/lib/rails/generators/actions.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt2
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb4
-rw-r--r--railties/lib/rails/railtie.rb2
-rw-r--r--railties/test/application/configuration_test.rb1
-rw-r--r--railties/test/application/middleware/cookies_test.rb47
-rw-r--r--railties/test/application/route_inspect_test.rb26
-rw-r--r--railties/test/generators/actions_test.rb8
-rw-r--r--railties/test/generators/orm_test.rb38
-rw-r--r--railties/test/railties/engine_test.rb132
24 files changed, 457 insertions, 71 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index b05ac21b49..6b0be4c096 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,20 +1,27 @@
## Rails 3.2.0 (unreleased) ##
+* Display mounted engine's routes in `rake routes`. *Piotr Sarnacki*
+
+* Allow to change the loading order of railties with `config.railties_order=` *Piotr Sarnacki*
+
+ Example:
+ config.railties_order = [Blog::Engine, :main_app, :all]
+
* Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box. *José Valim*
-* Updated Rails::Rack::Logger middleware to apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications *DHH*
+* Update Rails::Rack::Logger middleware to apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications *DHH*
* Default options to `rails new` can be set in ~/.railsrc *Guillermo Iguaran*
-* Added destroy alias to Rails engines. *Guillermo Iguaran*
+* Add destroy alias to Rails engines *Guillermo Iguaran*
-* Added destroy alias for Rails command line. This allows the following: `rails d model post`. *Andrey Ognevsky*
+* Add destroy alias for Rails command line. This allows the following: `rails d model post` *Andrey Ognevsky*
* Attributes on scaffold and model generators default to string. This allows the following: "rails g scaffold Post title body:text author" *José Valim*
-* Removed old plugin generator (`rails generate plugin`) in favor of `rails plugin new` command. *Guillermo Iguaran*
+* Remove old plugin generator (`rails generate plugin`) in favor of `rails plugin new` command *Guillermo Iguaran*
-* Removed old 'config.paths.app.controller' API in favor of 'config.paths["app/controller"]' API. *Guillermo Iguaran*
+* Remove old 'config.paths.app.controller' API in favor of 'config.paths["app/controller"]' API *Guillermo Iguaran*
* Rails 3.1.1
diff --git a/railties/guides/code/getting_started/app/views/layouts/application.html.erb b/railties/guides/code/getting_started/app/views/layouts/application.html.erb
index 1e1e4b9a99..7fd6b4f516 100644
--- a/railties/guides/code/getting_started/app/views/layouts/application.html.erb
+++ b/railties/guides/code/getting_started/app/views/layouts/application.html.erb
@@ -2,7 +2,7 @@
<html>
<head>
<title>Blog</title>
- <%= stylesheet_link_tag "application" %>
+ <%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index ad12dca7e8..c4724f182e 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -1287,6 +1287,7 @@ User.where(:id => 1).joins(:posts).explain
may yield
<plain>
+EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------------<plus>
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------------<plus>
@@ -1302,6 +1303,7 @@ Active Record performs a pretty printing that emulates the one of the database
shells. So, the same query running with the PostgreSQL adapter would yield instead
<plain>
+EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1
QUERY PLAN
------------------------------------------------------------------------------
Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
@@ -1324,12 +1326,15 @@ User.where(:id => 1).includes(:posts).explain
yields
<plain>
+EXPLAIN for: SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
| 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
1 row in set (0.00 sec)
+
+EXPLAIN for: SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` IN (1)
<plus>----<plus>-------------<plus>-------<plus>------<plus>---------------<plus>------<plus>---------<plus>------<plus>------<plus>-------------<plus>
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
<plus>----<plus>-------------<plus>-------<plus>------<plus>---------------<plus>------<plus>---------<plus>------<plus>------<plus>-------------<plus>
@@ -1339,3 +1344,14 @@ yields
</plain>
under MySQL.
+
+h4. Interpreting EXPLAIN
+
+Interpretation of the output of EXPLAIN is beyond the scope of this guide. The
+following pointers may be helpful:
+
+* SQLite3: "EXPLAIN QUERY PLAN":http://www.sqlite.org/eqp.html
+
+* MySQL: "EXPLAIN Output Format":http://dev.mysql.com/doc/refman/5.6/en/explain-output.html
+
+* PostgreSQL: "Using EXPLAIN":http://www.postgresql.org/docs/current/static/using-explain.html
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index ff6c5f967f..2dee440b3b 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -571,7 +571,7 @@ NOTE: Defined in +active_support/core_ext/module/attr_accessor_with_default.rb+.
h5. Internal Attributes
-When you are defining an attribute in a class that is meant to be subclassed name collisions are a risk. That's remarkably important for libraries.
+When you are defining an attribute in a class that is meant to be subclassed, name collisions are a risk. That's remarkably important for libraries.
Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby built-in +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
@@ -3039,15 +3039,30 @@ Active Support defines these methods as well for Ruby 1.8.
h6. +beginning_of_week+, +end_of_week+
-The methods +beginning_of_week+ and +end_of_week+ return the dates for the beginning and end of week, assuming weeks start on Monday:
+The methods +beginning_of_week+ and +end_of_week+ return the dates for the
+beginning and end of the week, respectively. Weeks are assumed to start on
+Monday, but that can be changed passing an argument.
<ruby>
-d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
-d.beginning_of_week # => Mon, 03 May 2010
-d.end_of_week # => Sun, 09 May 2010
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.beginning_of_week # => Mon, 03 May 2010
+d.beginning_of_week(:sunday) # => Sun, 02 May 2010
+d.end_of_week # => Sun, 09 May 2010
+d.end_of_week(:sunday) # => Sat, 08 May 2010
</ruby>
-+beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
++beginning_of_week+ is aliased to +at_beginning_of_week+ and +end_of_week+ is aliased to +at_end_of_week+.
+
+h6. +monday+, +sunday+
+
+The methods +monday+ and +sunday+ return the dates for the beginning and
+end of the week, respectively. Weeks are assumed to start on Monday.
+
+<ruby>
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.monday # => Mon, 03 May 2010
+d.sunday # => Sun, 09 May 2010
+</ruby>
h6. +prev_week+, +next_week+
@@ -3272,8 +3287,10 @@ The class +DateTime+ is a subclass of +Date+ so by loading +active_support/core_
<ruby>
yesterday
tomorrow
-beginning_of_week (monday, at_beginning_of_week)
-end_on_week (at_end_of_week)
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
weeks_ago
prev_week
next_week
@@ -3446,8 +3463,10 @@ ago
since (in)
beginning_of_day (midnight, at_midnight, at_beginning_of_day)
end_of_day
-beginning_of_week (monday, at_beginning_of_week)
-end_on_week (at_end_of_week)
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
weeks_ago
prev_week
next_week
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index cd6e7d116e..809948b41e 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -263,6 +263,8 @@ h4. Configuring Active Record
* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.
+* +config.active_record.identity_map+ controls whether the identity map is enabled, and is false by default.
+
The MySQL adapter adds one additional configuration option:
* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans and is true by default.
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index fde83ae730..ca6a404212 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -450,6 +450,8 @@ start a web server on your development machine. You can do this by running:
$ rails server
</shell>
+TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the absence of a runtime will give you an +execjs+ error. Usually Mac OS X and Windows come with a JavaScript runtime installed. +therubyracer+ and +therubyrhino+ are the commonly used runtimes for Ruby and JRuby respectively. You can also investigate a list of runtimes at "ExecJS":https://github.com/sstephenson/execjs.
+
This will fire up an instance of the WEBrick web server by default (Rails can
also use several other web servers). To see your application in action, open a
browser window and navigate to "http://localhost:3000":http://localhost:3000.
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 036b356a37..5ae9cf0f2b 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -17,7 +17,7 @@ As of Rails 3, +script/server+ has become +rails server+. This was done to centr
h4. +bin/rails+
-The actual +rails+ command is kept in _bin/rails_ at the and goes like this:
+The actual +rails+ command is kept in _bin/rails_:
<ruby>
#!/usr/bin/env ruby
@@ -31,7 +31,7 @@ rescue LoadError
end
</ruby>
-This file will attempt to load +rails/cli+ and if it cannot find it then add the +railties/lib+ path to the load path (+$:+) and will then try to require it again.
+This file will attempt to load +rails/cli+. If it cannot find it then +railties/lib+ is added to the load path (+$:+) before retrying.
h4. +railties/lib/rails/cli.rb+
@@ -56,7 +56,7 @@ else
end
</ruby>
-The +rbconfig+ file here is out of Ruby's standard library and provides us with the +RbConfig+ class which contains useful information dependent on how Ruby was compiled. We'll see this in use in +railties/lib/rails/script_rails_loader+.
+The +rbconfig+ file from the Ruby standard library provides us with the +RbConfig+ class which contains detailed information about the Ruby environment, including how Ruby was compiled. We can see this in use in +railties/lib/rails/script_rails_loader+.
<ruby>
require 'pathname'
@@ -71,7 +71,7 @@ module Rails
end
</ruby>
-The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +bin_dir+ and +ruby_install_name+ values for the configuration which will result in a path such as +/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby+, which is the default path on Mac OS X. If you're running Windows the path may be something such as +C:/Ruby192/bin/ruby+. Anyway, the path on your system may be different, but the point of this is that it will point at the known ruby executable location for your install. The +RbConfig::CONFIG["EXEEXT"]+ will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in +exec_script_rails!+. As for the +SCRIPT_RAILS+ constant, we'll see that when we get to the +in_rails_application?+ method.
+The +rails/script_rails_loader+ file uses +RbConfig::Config+ to obtain the +bin_dir+ and +ruby_install_name+ values for the configuration which together form the path to the Ruby interpreter. The +RbConfig::CONFIG["EXEEXT"]+ will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in +exec_script_rails!+. As for the +SCRIPT_RAILS+ constant, we'll see that when we get to the +in_rails_application?+ method.
Back in +rails/cli+, the next line is this:
@@ -79,7 +79,7 @@ Back in +rails/cli+, the next line is this:
Rails::ScriptRailsLoader.exec_script_rails!
</ruby>
-This method is defined in +rails/script_rails_loader+ like this:
+This method is defined in +rails/script_rails_loader+:
<ruby>
def self.exec_script_rails!
@@ -96,7 +96,7 @@ rescue SystemCallError
end
</ruby>
-This method will first check if the current working directory (+cwd+) is a Rails application or is a subdirectory of one. The way to determine this is defined in the +in_rails_application?+ method like this:
+This method will first check if the current working directory (+cwd+) is a Rails application or a subdirectory of one. This is determined by the +in_rails_application?+ method:
<ruby>
def self.in_rails_application?
@@ -104,7 +104,7 @@ def self.in_rails_application?
end
</ruby>
-The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+, then +in_rails_application_subdirectory?+ will be used:
+The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+ then +in_rails_application_subdirectory?+ will be used:
<ruby>
def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
@@ -112,17 +112,17 @@ def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
end
</ruby>
-This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory is reached which contains this file then this line will run:
+This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory containing this file is reached then this line will run:
<ruby>
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
</ruby>
-This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server".
+This is effectively the same as running +ruby script/rails [arguments]+, where +[arguments]+ at this point in time is simply "server".
h4. +script/rails+
-This file looks like this:
+This file is as follows:
<ruby>
APP_PATH = File.expand_path('../../config/application', __FILE__)
@@ -130,7 +130,7 @@ require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
</ruby>
-The +APP_PATH+ constant here will be used later in +rails/commands+. The +config/boot+ file that +script/rails+ references is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
+The +APP_PATH+ constant will be used later in +rails/commands+. The +config/boot+ file referenced here is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
h4. +config/boot.rb+
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 82fffe86bb..25ff74506a 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -123,10 +123,33 @@ module Rails
@env_config ||= super.merge({
"action_dispatch.parameter_filter" => config.filter_parameters,
"action_dispatch.secret_token" => config.secret_token,
- "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
+ "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
+ "action_dispatch.logger" => Rails.logger
})
end
+ def ordered_railties
+ @ordered_railties ||= begin
+ order = config.railties_order.map do |railtie|
+ if railtie == :main_app
+ self
+ elsif railtie.respond_to?(:instance)
+ railtie.instance
+ else
+ railtie
+ end
+ end
+
+ all = (railties.all - order)
+ all.push(self) unless all.include?(self)
+ order.push(:all) unless order.include?(:all)
+
+ index = order.index(:all)
+ order[index] = all
+ order.reverse.flatten
+ end
+ end
+
def initializers
Bootstrap.initializers_for(self) +
super +
@@ -141,6 +164,10 @@ module Rails
self
end
+ def helpers_paths
+ config.helpers_paths
+ end
+
protected
alias :build_middleware_stack :app
@@ -166,7 +193,7 @@ module Rails
middleware.use ::Rack::MethodOverride
middleware.use ::ActionDispatch::RequestId
middleware.use ::Rails::Rack::Logger, config.log_tags # must come after Rack::MethodOverride to properly log overridden methods
- middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local
+ middleware.use ::ActionDispatch::ShowExceptions
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
if config.action_dispatch.x_sendfile_header.present?
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 8f5b28faf8..e95b0f5495 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -10,8 +10,8 @@ module Rails
:dependency_loading, :filter_parameters,
:force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks,
:reload_plugins, :secret_token, :serve_static_assets,
- :ssl_options, :static_cache_control, :session_options,
- :time_zone, :whiny_nils
+ :ssl_options, :static_cache_control, :session_options,
+ :time_zone, :whiny_nils, :railties_order
attr_writer :log_level
attr_reader :encoding
@@ -35,6 +35,7 @@ module Rails
@middleware = app_middleware
@generators = app_generators
@cache_store = [ :file_store, "#{root}/tmp/cache/" ]
+ @railties_order = [:all]
@assets = ActiveSupport::OrderedOptions.new
@assets.enabled = false
diff --git a/railties/lib/rails/application/route_inspector.rb b/railties/lib/rails/application/route_inspector.rb
index 8252f21aa7..26652a8e5e 100644
--- a/railties/lib/rails/application/route_inspector.rb
+++ b/railties/lib/rails/application/route_inspector.rb
@@ -4,12 +4,23 @@ module Rails
# This class is just used for displaying route information when someone
# executes `rake routes`. People should not use this class.
class RouteInspector # :nodoc:
+ def initialize
+ @engines = ActiveSupport::OrderedHash.new
+ end
+
def format all_routes, filter = nil
if filter
all_routes = all_routes.select{ |route| route.defaults[:controller] == filter }
end
- routes = all_routes.collect do |route|
+ routes = collect_routes(all_routes)
+
+ formatted_routes(routes) +
+ formatted_routes_for_engines
+ end
+
+ def collect_routes(routes)
+ routes = routes.collect do |route|
route_reqs = route.requirements
rack_app = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/
@@ -25,12 +36,32 @@ module Rails
verb = route.verb.source.gsub(/[$^]/, '')
- {:name => route.name.to_s, :verb => verb, :path => route.path.spec.to_s, :reqs => reqs}
+ collect_engine_routes(reqs, rack_app)
+
+ {:name => route.name.to_s, :verb => verb, :path => route.path.spec.to_s, :reqs => reqs }
end
# Skip the route if it's internal info route
- routes.reject! { |r| r[:path] =~ %r{/rails/info/properties|^/assets} }
+ routes.reject { |r| r[:path] =~ %r{/rails/info/properties|^/assets} }
+ end
+
+ def collect_engine_routes(name, rack_app)
+ return unless rack_app && rack_app.respond_to?(:routes)
+ return if @engines[name]
+
+ routes = rack_app.routes
+ if routes.is_a?(ActionDispatch::Routing::RouteSet)
+ @engines[name] = collect_routes(routes.routes)
+ end
+ end
+
+ def formatted_routes_for_engines
+ @engines.map do |name, routes|
+ ["\nRoutes for #{name}:"] + formatted_routes(routes)
+ end.flatten
+ end
+ def formatted_routes(routes)
name_width = routes.map{ |r| r[:name].length }.max
verb_width = routes.map{ |r| r[:verb].length }.max
path_width = routes.map{ |r| r[:path].length }.max
diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb
index e6822b75b7..435ea83ad8 100644
--- a/railties/lib/rails/code_statistics.rb
+++ b/railties/lib/rails/code_statistics.rb
@@ -38,11 +38,22 @@ class CodeStatistics #:nodoc:
next unless file_name =~ pattern
f = File.open(directory + "/" + file_name)
-
+ comment_started = false
while line = f.gets
stats["lines"] += 1
- stats["classes"] += 1 if line =~ /class [A-Z]/
- stats["methods"] += 1 if line =~ /def [a-z]/
+ if(comment_started)
+ if line =~ /^=end/
+ comment_started = false
+ end
+ next
+ else
+ if line =~ /^=begin/
+ comment_started = true
+ next
+ end
+ end
+ stats["classes"] += 1 if line =~ /^\s*class\s+[_A-Z]/
+ stats["methods"] += 1 if line =~ /^\s*def\s+[_a-z]/
stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
end
end
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index b0ba76217a..4b0acc9d88 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -33,7 +33,7 @@ module Rails
options['mode'] = mode
end
- opt.on("-h", "--header") do |h|
+ opt.on("--header") do |h|
options['header'] = h
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index d652c6b7fe..5c1af99fe2 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -330,6 +330,17 @@ module Rails
#
# MyEngine::Engine.load_seed
#
+ # == Loading priority
+ #
+ # In order to change engine's priority you can use config.railties_order in main application.
+ # It will affect the priority of loading views, helpers, assets and all the other files
+ # related to engine or application.
+ #
+ # Example:
+ #
+ # # load Blog::Engine with highest priority, followed by application and other railties
+ # config.railties_order = [Blog::Engine, :main_app, :all]
+ #
class Engine < Railtie
autoload :Configuration, "rails/engine/configuration"
autoload :Railties, "rails/engine/railties"
@@ -371,20 +382,28 @@ module Rails
self.routes.default_scope = { :module => ActiveSupport::Inflector.underscore(mod.name) }
self.isolated = true
- unless mod.respond_to?(:_railtie)
- name = engine_name
- _railtie = self
+ unless mod.respond_to?(:railtie_namespace)
+ name, railtie = engine_name, self
+
mod.singleton_class.instance_eval do
- define_method(:_railtie) do
- _railtie
- end
+ define_method(:railtie_namespace) { railtie }
unless mod.respond_to?(:table_name_prefix)
- define_method(:table_name_prefix) do
- "#{name}_"
- end
+ define_method(:table_name_prefix) { "#{name}_" }
end
- end
+
+ unless mod.respond_to?(:use_relative_model_naming?)
+ class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__
+ end
+
+ unless mod.respond_to?(:railtie_helpers_paths)
+ define_method(:railtie_helpers_paths) { railtie.helpers_paths }
+ end
+
+ unless mod.respond_to?(:railtie_routes_url_helpers)
+ define_method(:railtie_routes_url_helpers) { railtie.routes_url_helpers }
+ end
+ end
end
end
@@ -429,13 +448,6 @@ module Rails
def helpers
@helpers ||= begin
helpers = Module.new
-
- helpers_paths = if config.respond_to?(:helpers_paths)
- config.helpers_paths
- else
- paths["app/helpers"].existent
- end
-
all = ActionController::Base.all_helpers_from_path(helpers_paths)
ActionController::Base.modules_for_helpers(all).each do |mod|
helpers.send(:include, mod)
@@ -444,6 +456,14 @@ module Rails
end
end
+ def helpers_paths
+ paths["app/helpers"].existent
+ end
+
+ def routes_url_helpers
+ routes.url_helpers
+ end
+
def app
@app ||= begin
config.middleware = config.middleware.merge_into(default_middleware_stack)
@@ -471,10 +491,19 @@ module Rails
@routes
end
+ def ordered_railties
+ railties.all + [self]
+ end
+
def initializers
initializers = []
- railties.all { |r| initializers += r.initializers }
- initializers += super
+ ordered_railties.each do |r|
+ if r == self
+ initializers += super
+ else
+ initializers += r.initializers
+ end
+ end
initializers
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index b26839644e..ca93f9ef9d 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -68,8 +68,9 @@ module Rails
end
in_root do
- str = "gem #{parts.join(", ")}\n"
+ str = "gem #{parts.join(", ")}"
str = " " + str if @in_group
+ str = "\n" + str
append_file "Gemfile", str, :verbose => false
end
end
@@ -87,13 +88,13 @@ module Rails
log :gemfile, "group #{name}"
in_root do
- append_file "Gemfile", "\ngroup #{name} do\n", :force => true
+ append_file "Gemfile", "\ngroup #{name} do", :force => true
@in_group = true
instance_eval(&block)
@in_group = false
- append_file "Gemfile", "end\n", :force => true
+ append_file "Gemfile", "\nend\n", :force => true
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
index c63d1b6ac5..bba96a7431 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
@@ -2,7 +2,7 @@
<html>
<head>
<title><%= camelized %></title>
- <%%= stylesheet_link_tag "application" %>
+ <%%= stylesheet_link_tag "application", :media => "all" %>
<%%= javascript_include_tag "application" %>
<%%= csrf_meta_tags %>
</head>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt
index 01550dec2f..bd983fb90f 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt
@@ -2,7 +2,7 @@
<html>
<head>
<title><%= camelized %></title>
- <%%= stylesheet_link_tag "<%= name %>/application" %>
+ <%%= stylesheet_link_tag "<%= name %>/application", :media => "all" %>
<%%= javascript_include_tag "<%= name %>/application" %>
<%%= csrf_meta_tags %>
</head>
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index b34bc4a524..3c5b39fa16 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -64,7 +64,7 @@ module Rails
end
begin
- "#{options[:orm].to_s.classify}::Generators::ActiveModel".constantize
+ "#{options[:orm].to_s.camelize}::Generators::ActiveModel".constantize
rescue NameError
Rails::Generators::ActiveModel
end
@@ -73,7 +73,7 @@ module Rails
# Initialize ORM::Generators::ActiveModel to access instance methods.
def orm_instance(name=singular_table_name)
- @orm_instance ||= @orm_class.new(name)
+ @orm_instance ||= orm_class.new(name)
end
end
end
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index e8fb1f3d98..f0991b99af 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -196,7 +196,7 @@ module Rails
end
def railtie_namespace
- @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:_railtie) }
+ @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) }
end
end
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index f356805d6e..f37a024a0b 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -524,6 +524,7 @@ module ApplicationTests
assert_equal app.env_config['action_dispatch.parameter_filter'], app.config.filter_parameters
assert_equal app.env_config['action_dispatch.secret_token'], app.config.secret_token
assert_equal app.env_config['action_dispatch.show_exceptions'], app.config.action_dispatch.show_exceptions
+ assert_equal app.env_config['action_dispatch.logger'], Rails.logger
end
end
end
diff --git a/railties/test/application/middleware/cookies_test.rb b/railties/test/application/middleware/cookies_test.rb
new file mode 100644
index 0000000000..13556cbed2
--- /dev/null
+++ b/railties/test/application/middleware/cookies_test.rb
@@ -0,0 +1,47 @@
+require 'isolation/abstract_unit'
+
+module ApplicationTests
+ class CookiesTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def new_app
+ File.expand_path("#{app_path}/../new_app")
+ end
+
+ def setup
+ build_app
+ boot_rails
+ FileUtils.rm_rf("#{app_path}/config/environments")
+ end
+
+ def teardown
+ teardown_app
+ FileUtils.rm_rf(new_app) if File.directory?(new_app)
+ end
+
+ test 'always_write_cookie is true by default in development' do
+ require 'rails'
+ Rails.env = 'development'
+ require "#{app_path}/config/environment"
+ assert_equal true, ActionDispatch::Cookies::CookieJar.always_write_cookie
+ end
+
+ test 'always_write_cookie is false by default in production' do
+ require 'rails'
+ Rails.env = 'production'
+ require "#{app_path}/config/environment"
+ assert_equal false, ActionDispatch::Cookies::CookieJar.always_write_cookie
+ end
+
+ test 'always_write_cookie can be overrided' do
+ add_to_config <<-RUBY
+ config.action_dispatch.always_write_cookie = false
+ RUBY
+
+ require 'rails'
+ Rails.env = 'development'
+ require "#{app_path}/config/environment"
+ assert_equal false, ActionDispatch::Cookies::CookieJar.always_write_cookie
+ end
+ end
+end
diff --git a/railties/test/application/route_inspect_test.rb b/railties/test/application/route_inspect_test.rb
index 78980705ed..2ad5ee6c4c 100644
--- a/railties/test/application/route_inspect_test.rb
+++ b/railties/test/application/route_inspect_test.rb
@@ -1,6 +1,7 @@
require 'test/unit'
require 'rails/application/route_inspector'
require 'action_controller'
+require 'rails/engine'
module ApplicationTests
class RouteInspectTest < Test::Unit::TestCase
@@ -9,6 +10,31 @@ module ApplicationTests
@inspector = Rails::Application::RouteInspector.new
end
+ def test_displaying_routes_for_engines
+ engine = Class.new(Rails::Engine) do
+ def self.to_s
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get '/cart', :to => 'cart#show'
+ end
+
+ @set.draw do
+ get '/custom/assets', :to => 'custom_assets#show'
+ mount engine => "/blog", :as => "blog"
+ end
+
+ output = @inspector.format @set.routes
+ expected = [
+ "custom_assets GET /custom/assets(.:format) custom_assets#show",
+ " blog /blog Blog::Engine",
+ "\nRoutes for Blog::Engine:",
+ "cart GET /cart(.:format) cart#show"
+ ]
+ assert_equal expected, output
+ end
+
def test_cart_inspect
@set.draw do
get '/cart', :to => 'cart#show'
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 51fa2fe16f..c1fd6a38f1 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -95,11 +95,13 @@ class ActionsTest < Rails::Generators::TestCase
def test_gem_should_insert_on_separate_lines
run_generator
+ File.open('Gemfile', 'a') {|f| f.write('# Some content...') }
+
action :gem, 'rspec'
action :gem, 'rspec-rails'
- assert_file 'Gemfile', /gem "rspec"$/
- assert_file 'Gemfile', /gem "rspec-rails"$/
+ assert_file 'Gemfile', /^gem "rspec"$/
+ assert_file 'Gemfile', /^gem "rspec-rails"$/
end
def test_gem_group_should_wrap_gems_in_a_group
@@ -112,7 +114,7 @@ class ActionsTest < Rails::Generators::TestCase
action :gem_group, :test do
gem 'fakeweb'
end
-
+
assert_file 'Gemfile', /\ngroup :development, :test do\n gem "rspec-rails"\nend\n\ngroup :test do\n gem "fakeweb"\nend/
end
diff --git a/railties/test/generators/orm_test.rb b/railties/test/generators/orm_test.rb
new file mode 100644
index 0000000000..9dd3d3e0ec
--- /dev/null
+++ b/railties/test/generators/orm_test.rb
@@ -0,0 +1,38 @@
+require "generators/generators_test_helper"
+require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
+
+# Mock out two ORMs
+module ORMWithGenerators
+ module Generators
+ class ActiveModel
+ def initialize(name)
+ end
+ end
+ end
+end
+
+module ORMWithoutGenerators
+ # No generators
+end
+
+class OrmTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::ScaffoldControllerGenerator
+
+ def test_orm_class_returns_custom_generator_if_supported_custom_orm_set
+ g = generator ["Foo"], :orm => "ORMWithGenerators"
+ assert_equal ORMWithGenerators::Generators::ActiveModel, g.send(:orm_class)
+ end
+
+ def test_orm_class_returns_rails_generator_if_unsupported_custom_orm_set
+ g = generator ["Foo"], :orm => "ORMWithoutGenerators"
+ assert_equal Rails::Generators::ActiveModel, g.send(:orm_class)
+ end
+
+ def test_orm_instance_returns_orm_class_instance_with_name
+ g = generator ["Foo"]
+ orm_instance = g.send(:orm_instance)
+ assert g.send(:orm_class) === orm_instance
+ assert_equal "foo", orm_instance.name
+ end
+end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 22dbcf9644..400cae98b2 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -323,7 +323,7 @@ module RailtiesTest
assert_equal "bukkits_", Bukkits.table_name_prefix
assert_equal "bukkits", Bukkits::Engine.engine_name
- assert_equal Bukkits._railtie, Bukkits::Engine
+ assert_equal Bukkits.railtie_namespace, Bukkits::Engine
assert ::Bukkits::MyMailer.method_defined?(:foo_path)
assert !::Bukkits::MyMailer.method_defined?(:bar_path)
@@ -467,7 +467,7 @@ module RailtiesTest
assert_nil Rails.application.load_seed
end
- test "using namespace more than once on one module should not overwrite _railtie method" do
+ test "using namespace more than once on one module should not overwrite railtie_namespace method" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module AppTemplate
class Engine < ::Rails::Engine
@@ -484,7 +484,7 @@ module RailtiesTest
boot_rails
- assert_equal AppTemplate._railtie, AppTemplate::Engine
+ assert_equal AppTemplate.railtie_namespace, AppTemplate::Engine
end
test "properly reload routes" do
@@ -667,6 +667,132 @@ module RailtiesTest
assert_equal expected, methods
end
+ test "setting priority for engines with config.railties_order" do
+ @blog = engine "blog" do |plugin|
+ plugin.write "lib/blog.rb", <<-RUBY
+ module Blog
+ class Engine < ::Rails::Engine
+ end
+ end
+ RUBY
+ end
+
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ isolate_namespace Bukkits
+ end
+ end
+ RUBY
+
+ controller "main", <<-RUBY
+ class MainController < ActionController::Base
+ def foo
+ render :inline => '<%= render :partial => "shared/foo" %>'
+ end
+
+ def bar
+ render :inline => '<%= render :partial => "shared/bar" %>'
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ match "/foo" => "main#foo"
+ match "/bar" => "main#bar"
+ end
+ RUBY
+
+ @plugin.write "app/views/shared/_foo.html.erb", <<-RUBY
+ Bukkit's foo partial
+ RUBY
+
+ app_file "app/views/shared/_foo.html.erb", <<-RUBY
+ App's foo partial
+ RUBY
+
+ @blog.write "app/views/shared/_bar.html.erb", <<-RUBY
+ Blog's bar partial
+ RUBY
+
+ app_file "app/views/shared/_bar.html.erb", <<-RUBY
+ App's bar partial
+ RUBY
+
+ @plugin.write "app/assets/javascripts/foo.js", <<-RUBY
+ // Bukkit's foo js
+ RUBY
+
+ app_file "app/assets/javascripts/foo.js", <<-RUBY
+ // App's foo js
+ RUBY
+
+ @blog.write "app/assets/javascripts/bar.js", <<-RUBY
+ // Blog's bar js
+ RUBY
+
+ app_file "app/assets/javascripts/bar.js", <<-RUBY
+ // App's bar js
+ RUBY
+
+ add_to_config("config.railties_order = [:all, :main_app, Blog::Engine]")
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ get("/foo")
+ assert_equal "Bukkit's foo partial", last_response.body.strip
+
+ get("/bar")
+ assert_equal "App's bar partial", last_response.body.strip
+
+ get("/assets/foo.js")
+ assert_equal "// Bukkit's foo js\n;", last_response.body.strip
+
+ get("/assets/bar.js")
+ assert_equal "// App's bar js\n;", last_response.body.strip
+ end
+
+ test "railties_order adds :all with lowest priority if not given" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ end
+ end
+ RUBY
+
+ controller "main", <<-RUBY
+ class MainController < ActionController::Base
+ def foo
+ render :inline => '<%= render :partial => "shared/foo" %>'
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ match "/foo" => "main#foo"
+ end
+ RUBY
+
+ @plugin.write "app/views/shared/_foo.html.erb", <<-RUBY
+ Bukkit's foo partial
+ RUBY
+
+ app_file "app/views/shared/_foo.html.erb", <<-RUBY
+ App's foo partial
+ RUBY
+
+ add_to_config("config.railties_order = [Bukkits::Engine]")
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ get("/foo")
+ assert_equal "Bukkit's foo partial", last_response.body.strip
+ end
+
private
def app
Rails.application