aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md11
-rw-r--r--railties/guides/code/getting_started/config/environments/development.rb7
-rw-r--r--railties/guides/code/getting_started/config/environments/production.rb4
-rw-r--r--railties/guides/source/active_record_querying.textile21
-rw-r--r--railties/guides/source/configuring.textile2
-rw-r--r--railties/guides/source/form_helpers.textile2
-rw-r--r--railties/lib/rails/application.rb3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt6
-rw-r--r--railties/test/application/assets_test.rb22
-rw-r--r--railties/test/application/middleware/exceptions_test.rb89
-rw-r--r--railties/test/application/middleware/show_exceptions_test.rb41
-rw-r--r--railties/test/application/middleware_test.rb24
-rw-r--r--railties/test/generators/app_generator_test.rb9
14 files changed, 177 insertions, 68 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 6b0be4c096..64abff6cb3 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,13 +1,20 @@
## Rails 3.2.0 (unreleased) ##
-* Display mounted engine's routes in `rake routes`. *Piotr Sarnacki*
+* New applications get a flag
+ `config.active_record.auto_explain_threshold_in_seconds` in the evironments
+ configuration files. With a value of 0.5 in development.rb, and commented
+ out in production.rb. No mention in test.rb. *fxn*
+
+* Add DebugExceptions middleware which contains features extracted from ShowExceptions middleware *José Valim*
+
+* 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*
+* Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box *José Valim*
* 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*
diff --git a/railties/guides/code/getting_started/config/environments/development.rb b/railties/guides/code/getting_started/config/environments/development.rb
index 89932bf19b..d60a10568b 100644
--- a/railties/guides/code/getting_started/config/environments/development.rb
+++ b/railties/guides/code/getting_started/config/environments/development.rb
@@ -22,6 +22,13 @@ Blog::Application.configure do
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
+ # Raise exception on mass assignment protection for ActiveRecord models
+ config.active_record.mass_assignment_sanitizer = :strict
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ config.active_record.auto_explain_threshold_in_seconds = 0.5
+
# Do not compress assets
config.assets.compress = false
diff --git a/railties/guides/code/getting_started/config/environments/production.rb b/railties/guides/code/getting_started/config/environments/production.rb
index dee8acfdfe..c9b2f41c39 100644
--- a/railties/guides/code/getting_started/config/environments/production.rb
+++ b/railties/guides/code/getting_started/config/environments/production.rb
@@ -60,4 +60,8 @@ Blog::Application.configure do
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ # config.active_record.auto_explain_threshold_in_seconds = 0.5
end
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 073f7c143d..352f23dc01 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -1148,11 +1148,26 @@ Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
h3. +pluck+
-<tt>pluck</tt> can be used to query single column from table under model. It accepts column name as argument and returns Array of values of the specified column with corresponding data type.
+<tt>pluck</tt> can be used to query a single column from the underlying table of a model. It accepts a column name as argument and returns an array of values of the specified column with the corresponding data type.
<ruby>
-Client.where(:active => true).pluck(:id) # SELECT id FROM clients WHERE clients.active
-Client.uniq.pluck(:role) # SELECT DISTINCT role FROM clients
+Client.where(:active => true).pluck(:id)
+# SELECT id FROM clients WHERE active = 1
+
+Client.uniq.pluck(:role)
+# SELECT DISTINCT role FROM clients
+</ruby>
+
++pluck+ makes it possible to replace code like
+
+<ruby>
+Client.select(:id).map { |c| c.id }
+</ruby>
+
+with
+
+<ruby>
+Client.pluck(:id)
</ruby>
h3. Existence of Objects
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index d91011c370..8e65dbccbb 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -268,6 +268,8 @@ h4. Configuring Active Record
* +config.active_record.identity_map+ controls whether the identity map is enabled, and is false by default.
+* +config.active_record.auto_explain_threshold_in_seconds+ configures the threshold for automatic EXPLAINs (+nil+ disables this feature). Queries exceeding the threshold get their query plan logged. Default is 0.5 in development mode.
+
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/form_helpers.textile b/railties/guides/source/form_helpers.textile
index 821bb305f6..64eb2d8f36 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -229,7 +229,7 @@ The corresponding view +app/views/articles/new.html.erb+ using +form_for+ looks
There are a few things to note here:
# +@article+ is the actual object being edited.
-# There is a single hash of options. Routing options are passed in the +:url+ hash, HTML options are passed in the +:html+ hash.
+# There is a single hash of options. Routing options are passed in the +:url+ hash, HTML options are passed in the +:html+ hash. Also you can provide a +:namespace+ option for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generated HTML id.
# The +form_for+ method yields a *form builder* object (the +f+ variable).
# Methods to create form controls are called *on* the form builder object +f+
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 2a62446a04..f5f47acfbc 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -195,10 +195,13 @@ module Rails
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
+ middleware.use ::ActionDispatch::DebugExceptions
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
end
+
middleware.use ::ActionDispatch::Reloader unless config.cache_classes
middleware.use ::ActionDispatch::Callbacks
middleware.use ::ActionDispatch::Cookies
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index 47078e3af9..beaf941282 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -25,6 +25,10 @@
<%- unless options.skip_active_record? -%>
# Raise exception on mass assignment protection for ActiveRecord models
config.active_record.mass_assignment_sanitizer = :strict
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ config.active_record.auto_explain_threshold_in_seconds = 0.5
<%- end -%>
# Do not compress assets
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 50f2df3d35..40ec3fc644 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -60,4 +60,10 @@
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
+
+ <%- unless options.skip_active_record? -%>
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ # config.active_record.auto_explain_threshold_in_seconds = 0.5
+ <%- end -%>
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index d4ffbe3d66..a22013f81c 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -451,6 +451,28 @@ module ApplicationTests
assert_equal 0, files.length, "Expected application.js asset to be removed, but still exists"
end
+ test "asset urls should use the request's protocol by default" do
+ app_with_assets_in_view
+ add_to_config "config.asset_host = 'example.com'"
+ require "#{app_path}/config/environment"
+ class ::PostsController < ActionController::Base; end
+
+ get '/posts', {}, {'HTTPS'=>'off'}
+ assert_match('src="http://example.com/assets/application.js', last_response.body)
+ get '/posts', {}, {'HTTPS'=>'on'}
+ assert_match('src="https://example.com/assets/application.js', last_response.body)
+ end
+
+ test "asset urls should be protocol-relative if no request is in scope" do
+ app_file "app/assets/javascripts/image_loader.js.erb", 'var src="<%= image_path("rails.png") %>";'
+ add_to_config "config.assets.precompile = %w{image_loader.js}"
+ add_to_config "config.asset_host = 'example.com'"
+ precompile!
+
+ assert_match 'src="//example.com/assets/rails.png"', File.read("#{app_path}/public/assets/image_loader.js")
+ end
+
+
private
def app_with_assets_in_view
diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb
new file mode 100644
index 0000000000..0174352900
--- /dev/null
+++ b/railties/test/application/middleware/exceptions_test.rb
@@ -0,0 +1,89 @@
+# encoding: utf-8
+require 'isolation/abstract_unit'
+require 'rack/test'
+
+module ApplicationTests
+ class MiddlewareExceptionsTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test "show exceptions middleware filter backtrace before logging" do
+ my_middleware = Struct.new(:app) do
+ def call(env)
+ raise "Failure"
+ end
+ end
+
+ app.config.middleware.use my_middleware
+
+ stringio = StringIO.new
+ Rails.logger = Logger.new(stringio)
+
+ get "/"
+ assert_no_match(/action_dispatch/, stringio.string)
+ end
+
+ test "renders active record exceptions as 404" do
+ my_middleware = Struct.new(:app) do
+ def call(env)
+ raise ActiveRecord::RecordNotFound
+ end
+ end
+
+ app.config.middleware.use my_middleware
+
+ get "/"
+ assert_equal 404, last_response.status
+ end
+
+ test "unspecified route when set action_dispatch.show_exceptions to false" do
+ app.config.action_dispatch.show_exceptions = false
+
+ assert_raise(ActionController::RoutingError) do
+ get '/foo'
+ end
+ end
+
+ test "unspecified route when set action_dispatch.show_exceptions to true" do
+ app.config.action_dispatch.show_exceptions = true
+
+ assert_nothing_raised(ActionController::RoutingError) do
+ get '/foo'
+ end
+ end
+
+ test "displays diagnostics message when exception raised in template that contains UTF-8" do
+ app.config.action_dispatch.show_exceptions = true
+
+ controller :foo, <<-RUBY
+ class FooController < ActionController::Base
+ def index
+ end
+ end
+ RUBY
+
+ app_file 'app/views/foo/index.html.erb', <<-ERB
+ <% raise 'boooom' %>
+ ✓
+ ERB
+
+ app_file 'config/routes.rb', <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match ':controller(/:action)'
+ end
+ RUBY
+
+ post '/foo', :utf8 => '✓'
+ assert_match(/boooom/, last_response.body)
+ end
+ end
+end
diff --git a/railties/test/application/middleware/show_exceptions_test.rb b/railties/test/application/middleware/show_exceptions_test.rb
deleted file mode 100644
index e3f27f63c3..0000000000
--- a/railties/test/application/middleware/show_exceptions_test.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require 'isolation/abstract_unit'
-
-module ApplicationTests
- class ShowExceptionsTest < Test::Unit::TestCase
- include ActiveSupport::Testing::Isolation
-
- def setup
- build_app
- boot_rails
- FileUtils.rm_rf "#{app_path}/config/environments"
- end
-
- def teardown
- teardown_app
- end
-
- def app
- @app ||= Rails.application
- end
-
- test "unspecified route when set action_dispatch.show_exceptions to false" do
- make_basic_app do |app|
- app.config.action_dispatch.show_exceptions = false
- end
-
- assert_raise(ActionController::RoutingError) do
- get '/foo'
- end
- end
-
- test "unspecified route when set action_dispatch.show_exceptions to true" do
- make_basic_app do |app|
- app.config.action_dispatch.show_exceptions = true
- end
-
- assert_nothing_raised(ActionController::RoutingError) do
- get '/foo'
- end
- end
- end
-end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 4703a59326..578370cfca 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -33,6 +33,7 @@ module ApplicationTests
"ActionDispatch::RequestId",
"Rails::Rack::Logger", # must come after Rack::MethodOverride to properly log overridden methods
"ActionDispatch::ShowExceptions",
+ "ActionDispatch::DebugExceptions",
"ActionDispatch::RemoteIp",
"Rack::Sendfile",
"ActionDispatch::Reloader",
@@ -104,10 +105,11 @@ module ApplicationTests
assert !middleware.include?("ActionDispatch::Static")
end
- test "includes show exceptions even action_dispatch.show_exceptions is disabled" do
+ test "includes exceptions middlewares even if action_dispatch.show_exceptions is disabled" do
add_to_config "config.action_dispatch.show_exceptions = false"
boot!
assert middleware.include?("ActionDispatch::ShowExceptions")
+ assert middleware.include?("ActionDispatch::DebugExceptions")
end
test "removes ActionDispatch::Reloader if cache_classes is true" do
@@ -191,26 +193,6 @@ module ApplicationTests
assert_equal nil, last_response.headers["Etag"]
end
- # Show exceptions middleware
- test "show exceptions middleware filter backtrace before logging" do
- my_middleware = Struct.new(:app) do
- def call(env)
- raise "Failure"
- end
- end
-
- make_basic_app do |app|
- app.config.middleware.use my_middleware
- end
-
- stringio = StringIO.new
- Rails.logger = Logger.new(stringio)
-
- env = Rack::MockRequest.env_for("/")
- Rails.application.call(env)
- assert_no_match(/action_dispatch/, stringio.string)
- end
-
private
def boot!
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 235c08e38e..41bb4d8b20 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -336,6 +336,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generated_environments_file_for_auto_explain
+ run_generator [destination_root, "--skip-active-record"]
+ %w(development test production).each do |env|
+ assert_file "config/environments/#{env}.rb" do |file|
+ assert_no_match %r(auto_explain_threshold_in_seconds), file
+ end
+ end
+ end
+
protected
def action(*args, &block)