aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--actioncable/lib/action_cable/connection/base.rb9
-rw-r--r--actioncable/lib/action_cable/connection/subscriptions.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/ssl.rb26
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb9
-rw-r--r--actionpack/test/dispatch/middleware_stack_test.rb16
-rw-r--r--actionview/CHANGELOG.md5
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/number_helper.rb8
-rw-r--r--actionview/lib/action_view/template/resolver.rb2
-rw-r--r--actionview/test/template/form_tag_helper_test.rb7
-rw-r--r--activejob/CHANGELOG.md2
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb11
-rw-r--r--activemodel/test/cases/validations/numericality_validation_test.rb42
-rw-r--r--activerecord/CHANGELOG.md23
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb15
-rw-r--r--activerecord/lib/active_record/relation.rb4
-rw-r--r--activerecord/test/cases/base_test.rb1
-rw-r--r--activerecord/test/cases/column_definition_test.rb10
-rw-r--r--activesupport/CHANGELOG.md24
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb2
-rw-r--r--activesupport/lib/active_support/logger.rb14
-rw-r--r--activesupport/lib/active_support/logger_silence.rb24
-rw-r--r--activesupport/lib/active_support/number_helper.rb8
-rw-r--r--activesupport/test/logger_test.rb85
-rw-r--r--guides/source/5_0_release_notes.md335
-rw-r--r--guides/source/action_view_overview.md2
-rw-r--r--guides/source/configuring.md4
-rw-r--r--guides/source/routing.md2
-rw-r--r--railties/lib/rails/generators/app_base.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/README.md27
-rw-r--r--railties/lib/rails/test_unit/minitest_plugin.rb20
-rw-r--r--railties/lib/rails/test_unit/reporter.rb32
-rw-r--r--railties/test/test_unit/reporter_test.rb38
37 files changed, 722 insertions, 105 deletions
diff --git a/.travis.yml b/.travis.yml
index f1031a3750..5c2699371b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,6 +25,7 @@ env:
- "GEM=guides"
rvm:
- 2.2.4
+ - 2.3.0
- ruby-head
matrix:
allow_failures:
diff --git a/actioncable/lib/action_cable/connection/base.rb b/actioncable/lib/action_cable/connection/base.rb
index f7b18a85ae..977856d656 100644
--- a/actioncable/lib/action_cable/connection/base.rb
+++ b/actioncable/lib/action_cable/connection/base.rb
@@ -48,11 +48,9 @@ module ActionCable
include InternalChannel
include Authorization
- attr_reader :server, :env, :subscriptions
+ attr_reader :server, :env, :subscriptions, :logger
delegate :worker_pool, :pubsub, to: :server
- attr_reader :logger
-
def initialize(server, env)
@server, @env = server, env
@@ -123,7 +121,6 @@ module ActionCable
transmit ActiveSupport::JSON.encode(identifier: ActionCable::INTERNAL[:identifiers][:ping], message: Time.now.to_i)
end
-
protected
# The request that initiated the WebSocket connection is available here. This gives access to the environment, cookies, etc.
def request
@@ -138,8 +135,6 @@ module ActionCable
request.cookie_jar
end
-
- protected
attr_reader :websocket
attr_reader :message_buffer
@@ -170,7 +165,6 @@ module ActionCable
disconnect if respond_to?(:disconnect)
end
-
def allow_request_origin?
return true if server.config.disable_request_forgery_protection
@@ -193,7 +187,6 @@ module ActionCable
[ 404, { 'Content-Type' => 'text/plain' }, [ 'Page not found' ] ]
end
-
# Tags are declared in the server but computed in the connection. This allows us per-connection tailored tags.
def new_tagged_logger
TaggedLoggerProxy.new server.logger,
diff --git a/actioncable/lib/action_cable/connection/subscriptions.rb b/actioncable/lib/action_cable/connection/subscriptions.rb
index 65d6634bb0..d7f95e6a62 100644
--- a/actioncable/lib/action_cable/connection/subscriptions.rb
+++ b/actioncable/lib/action_cable/connection/subscriptions.rb
@@ -49,7 +49,6 @@ module ActionCable
find(data).perform_action ActiveSupport::JSON.decode(data['data'])
end
-
def identifiers
subscriptions.keys
end
diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb
index 47f475559a..8f8f1bab8b 100644
--- a/actionpack/lib/action_dispatch/middleware/ssl.rb
+++ b/actionpack/lib/action_dispatch/middleware/ssl.rb
@@ -1,19 +1,21 @@
module ActionDispatch
- # This middleware is added to the stack when `config.force_ssl = true`.
- # It does three jobs to enforce secure HTTP requests:
+ # This middleware is added to the stack when `config.force_ssl = true`, and is passed
+ # the options set in `config.ssl_options`. It does three jobs to enforce secure HTTP
+ # requests:
#
- # 1. TLS redirect. http:// requests are permanently redirected to https://
- # with the same URL host, path, etc. Pass `:host` and/or `:port` to
- # modify the destination URL. This is always enabled.
+ # 1. TLS redirect: Permanently redirects http:// requests to https://
+ # with the same URL host, path, etc. This is always enabled. Set
+ # `config.ssl_options` to modify the destination URL
+ # (e.g. `redirect: { host: "secure.widgets.com", port: 8080 }`)
#
- # 2. Secure cookies. Sets the `secure` flag on cookies to tell browsers they
+ # 2. Secure cookies: Sets the `secure` flag on cookies to tell browsers they
# mustn't be sent along with http:// requests. This is always enabled.
#
- # 3. HTTP Strict Transport Security (HSTS). Tells the browser to remember
+ # 3. HTTP Strict Transport Security (HSTS): Tells the browser to remember
# this site as TLS-only and automatically redirect non-TLS requests.
# Enabled by default. Pass `hsts: false` to disable.
#
- # Configure HSTS with `hsts: { … }`:
+ # Set `config.ssl_options` with `hsts: { … }` to configure HSTS:
# * `expires`: How long, in seconds, these settings will stick. Defaults to
# `180.days` (recommended). The minimum required to qualify for browser
# preload lists is `18.weeks`.
@@ -26,10 +28,10 @@ module ActionDispatch
# gap, browser vendors include a baked-in list of HSTS-enabled sites.
# Go to https://hstspreload.appspot.com to submit your site for inclusion.
#
- # Disabling HSTS: To turn off HSTS, omitting the header is not enough.
- # Browsers will remember the original HSTS directive until it expires.
- # Instead, use the header to tell browsers to expire HSTS immediately.
- # Setting `hsts: false` is a shortcut for `hsts: { expires: 0 }`.
+ # To turn off HSTS, omitting the header is not enough. Browsers will remember the
+ # original HSTS directive until it expires. Instead, use the header to tell browsers to
+ # expire HSTS immediately. Setting `hsts: false` is a shortcut for
+ # `hsts: { expires: 0 }`.
class SSL
# Default to 180 days, the low end for https://www.ssllabs.com/ssltest/
# and greater than the 18-week requirement for browser preload lists.
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index 44fc1ee736..0b4bee5462 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -14,6 +14,15 @@ module ActionDispatch
def name; klass.name; end
+ def ==(middleware)
+ case middleware
+ when Middleware
+ klass == middleware.klass
+ when Class
+ klass == middleware
+ end
+ end
+
def inspect
if klass.is_a?(Class)
klass.to_s
diff --git a/actionpack/test/dispatch/middleware_stack_test.rb b/actionpack/test/dispatch/middleware_stack_test.rb
index 33aa616474..a8c8e0784f 100644
--- a/actionpack/test/dispatch/middleware_stack_test.rb
+++ b/actionpack/test/dispatch/middleware_stack_test.rb
@@ -131,4 +131,20 @@ class MiddlewareStackTest < ActiveSupport::TestCase
assert_equal BazMiddleware, @stack.last.klass
end
end
+
+ test "can check if Middleware are equal - Class" do
+ assert_equal @stack.last, BarMiddleware
+ end
+
+ test "includes a class" do
+ assert_equal true, @stack.include?(BarMiddleware)
+ end
+
+ test "can check if Middleware are equal - Middleware" do
+ assert_equal @stack.last, @stack.last
+ end
+
+ test "includes a middleware" do
+ assert_equal true, @stack.include?(ActionDispatch::MiddlewareStack::Middleware.new(BarMiddleware, nil, nil))
+ end
end
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index a43d9039db..85d91825ac 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Fix regression in `submit_tag` when a symbol is used as label argument.
+
+ *Yuuji Yaginuma*
+
+
## Rails 5.0.0.beta1 (December 18, 2015) ##
* `I18n.translate` helper will wrap the missing translation keys
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 0191064326..79a1a242bf 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -447,7 +447,7 @@ module ActionView
unless tag_options["data-disable-with"] == false || (tag_options["data"] && tag_options["data"][:disable_with] == false)
disable_with_text = tag_options["data-disable-with"]
disable_with_text ||= tag_options["data"][:disable_with] if tag_options["data"]
- disable_with_text ||= value.clone
+ disable_with_text ||= value.to_s.clone
tag_options.deep_merge!("data" => { "disable_with" => disable_with_text })
else
tag_options["data"].delete(:disable_with) if tag_options["data"]
diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb
index 0c5cecae01..161aa031c6 100644
--- a/actionview/lib/action_view/helpers/number_helper.rb
+++ b/actionview/lib/action_view/helpers/number_helper.rb
@@ -63,6 +63,14 @@ module ActionView
# Formats a +number+ into a currency string (e.g., $13.65). You
# can customize the format in the +options+ hash.
#
+ # The currency unit and number formatting of the current locale will be used
+ # unless otherwise specified in the provided options. No currency conversion
+ # is performed. If the user is given a way to change their locale, they will
+ # also be able to change the relative value of the currency displayed with
+ # this helper. If your application will ever support multiple locales, you
+ # may want to specify a constant <tt>:locale</tt> option or consider
+ # using a library capable of currency conversion.
+ #
# ==== Options
#
# * <tt>:locale</tt> - Sets the locale to be used for formatting
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index 7859c58b43..6ddd2b66b3 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -3,7 +3,7 @@ require "active_support/core_ext/class"
require "active_support/core_ext/module/attribute_accessors"
require "action_view/template"
require "thread"
-require "concurrent"
+require "concurrent/map"
module ActionView
# = Action View Resolver
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index de1eb89dc5..359ecbc637 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -510,6 +510,13 @@ class FormTagHelperTest < ActionView::TestCase
)
end
+ def test_submit_tag_with_symbol_value
+ assert_dom_equal(
+ %(<input data-disable-with="Save" name='commit' type="submit" value="Save" />),
+ submit_tag(:Save)
+ )
+ end
+
def test_button_tag
assert_dom_equal(
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md
index c4c49af53a..8687af5eba 100644
--- a/activejob/CHANGELOG.md
+++ b/activejob/CHANGELOG.md
@@ -28,7 +28,7 @@
*Jean Boussier*
-* Include I18n.locale into job serialization/deserialization and use it around
+* Include `I18n.locale` into job serialization/deserialization and use it around
`perform`.
Fixes #20799.
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index 9c1e8b4ba7..ad7012df48 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -39,6 +39,10 @@ module ActiveModel
return
end
+ unless raw_value.is_a?(Numeric)
+ value = parse_raw_value_as_a_number(raw_value)
+ end
+
options.slice(*CHECKS.keys).each do |option, option_value|
case option
when :odd, :even
@@ -63,12 +67,15 @@ module ActiveModel
protected
def is_number?(raw_value)
- parsed_value = Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
- !parsed_value.nil?
+ !parse_raw_value_as_a_number(raw_value).nil?
rescue ArgumentError, TypeError
false
end
+ def parse_raw_value_as_a_number(raw_value)
+ Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
+ end
+
def is_integer?(raw_value)
/\A[+-]?\d+\z/ === raw_value.to_s
end
diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb
index 04ec74bad3..74a048537d 100644
--- a/activemodel/test/cases/validations/numericality_validation_test.rb
+++ b/activemodel/test/cases/validations/numericality_validation_test.rb
@@ -79,6 +79,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([97.18, 98, BigDecimal.new('98')]) # Notice the 97.18 as a float is greater than 97.18 as a BigDecimal due to floating point precision
end
+ def test_validates_numericality_with_greater_than_using_string_value
+ Topic.validates_numericality_of :approved, greater_than: 10
+
+ invalid!(['-10', '9', '9.9', '10'], 'must be greater than 10')
+ valid!(['10.1', '11'])
+ end
+
def test_validates_numericality_with_greater_than_or_equal
Topic.validates_numericality_of :approved, greater_than_or_equal_to: 10
@@ -93,6 +100,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([97.18, 98, BigDecimal.new('97.19')])
end
+ def test_validates_numericality_with_greater_than_or_equal_using_string_value
+ Topic.validates_numericality_of :approved, greater_than_or_equal_to: 10
+
+ invalid!(['-10', '9', '9.9'], 'must be greater than or equal to 10')
+ valid!(['10', '10.1', '11'])
+ end
+
def test_validates_numericality_with_equal_to
Topic.validates_numericality_of :approved, equal_to: 10
@@ -107,6 +121,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([BigDecimal.new('97.18')])
end
+ def test_validates_numericality_with_equal_to_using_string_value
+ Topic.validates_numericality_of :approved, equal_to: 10
+
+ invalid!(['-10', '9', '9.9', '10.1', '11'], 'must be equal to 10')
+ valid!(['10'])
+ end
+
def test_validates_numericality_with_less_than
Topic.validates_numericality_of :approved, less_than: 10
@@ -121,6 +142,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([-97.0, 97.0, -97, 97, BigDecimal.new('-97'), BigDecimal.new('97')])
end
+ def test_validates_numericality_with_less_than_using_string_value
+ Topic.validates_numericality_of :approved, less_than: 10
+
+ invalid!(['10', '10.1', '11'], 'must be less than 10')
+ valid!(['-10', '9', '9.9'])
+ end
+
def test_validates_numericality_with_less_than_or_equal_to
Topic.validates_numericality_of :approved, less_than_or_equal_to: 10
@@ -135,6 +163,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([-97.18, BigDecimal.new('-97.18'), BigDecimal.new('97.18')])
end
+ def test_validates_numericality_with_less_than_or_equal_using_string_value
+ Topic.validates_numericality_of :approved, less_than_or_equal_to: 10
+
+ invalid!(['10.1', '11'], 'must be less than or equal to 10')
+ valid!(['-10', '9', '9.9', '10'])
+ end
+
def test_validates_numericality_with_odd
Topic.validates_numericality_of :approved, odd: true
@@ -163,6 +198,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
valid!([-1, 42])
end
+ def test_validates_numericality_with_other_than_using_string_value
+ Topic.validates_numericality_of :approved, other_than: 0
+
+ invalid!(['0', '0.0'])
+ valid!(['-1', '1.1', '42'])
+ end
+
def test_validates_numericality_with_proc
Topic.send(:define_method, :min_approved, lambda { 5 })
Topic.validates_numericality_of :approved, greater_than_or_equal_to: Proc.new(&:min_approved)
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index fb6c5e7e81..2551841aaf 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -50,7 +50,7 @@
change, passing a string containing a comma to `limit` has been deprecated,
and passing an Arel node to `limit` is no longer supported.
- Fixes #22250
+ Fixes #22250.
*Sean Griffin*
@@ -312,7 +312,7 @@
* Don't cache arguments in `#find_by` if they are an `ActiveRecord::Relation`.
- Fixes #20817
+ Fixes #20817.
*Hiroaki Izu*
@@ -441,9 +441,9 @@
* Ensure `select` quotes aliased attributes, even when using `from`.
- Fixes #21488
+ Fixes #21488.
- *Sean Griffin & @johanlunds*
+ *Sean Griffin*, *@johanlunds*
* MySQL: support `unsigned` numeric data types.
@@ -769,7 +769,7 @@
* Include the `Enumerable` module in `ActiveRecord::Relation`
- *Sean Griffin & bogdan*
+ *Sean Griffin*, *bogdan*
* Use `Enumerable#sum` in `ActiveRecord::Relation` if a block is given.
@@ -805,7 +805,7 @@
Fixes #20515.
- *Sean Griffin & jmondo*
+ *Sean Griffin*, *jmondo*
* Deprecate the PostgreSQL `:point` type in favor of a new one which will return
`Point` objects instead of an `Array`
@@ -1195,13 +1195,16 @@
*Sean Griffin*
* `scoping` no longer pollutes the current scope of sibling classes when using
- STI. e.x.
+ STI.
+
+ Fixes #18806.
+
+ Example:
StiOne.none.scoping do
StiTwo.all
end
- Fixes #18806.
*Sean Griffin*
@@ -1242,7 +1245,7 @@
* Use `SCHEMA` instead of `DB_STRUCTURE` for specifying a structure file.
- This makes the db:structure tasks consistent with test:load_structure.
+ This makes the `db:structure` tasks consistent with `test:load_structure`.
*Dieter Komendera*
@@ -1278,7 +1281,7 @@
Fixes #17621.
- *Eileen M. Uchitelle, Aaron Patterson*
+ *Eileen M. Uchitelle*, *Aaron Patterson*
* Fix n+1 query problem when eager loading nil associations (fixes #18312)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 7e0b449c99..d3bc378bea 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -344,18 +344,12 @@ module ActiveRecord
# The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
# on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
# an UPDATE statement, so in the MySQL adapters we redefine this to do that.
- def join_to_update(update, select) #:nodoc:
- key = update.key
+ def join_to_update(update, select, key) # :nodoc:
subselect = subquery_for(key, select)
update.where key.in(subselect)
end
-
- def join_to_delete(delete, select, key) #:nodoc:
- subselect = subquery_for(key, select)
-
- delete.where key.in(subselect)
- end
+ alias join_to_delete join_to_update
protected
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index af10703e0e..37e4eb24a8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -31,8 +31,6 @@ module ActiveRecord
def extract_default
if blob_or_text_column?
@default = null || strict ? nil : ''
- elsif missing_default_forged_as_empty_string?(default)
- @default = nil
end
end
@@ -59,17 +57,6 @@ module ActiveRecord
private
- # MySQL misreports NOT NULL column default when none is given.
- # We can't detect this for columns which may have a legitimate ''
- # default (string) but we can for others (integer, datetime, boolean,
- # and the rest).
- #
- # Test whether the column has default '', is not null, and is not
- # a type allowing default ''.
- def missing_default_forged_as_empty_string?(default)
- type != :string && !null && default == ''
- end
-
def assert_valid_default(default)
if blob_or_text_column? && default.present?
raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
@@ -431,7 +418,7 @@ module ActiveRecord
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
# these, we must use a subquery.
- def join_to_update(update, select) #:nodoc:
+ def join_to_update(update, select, key) # :nodoc:
if select.limit || select.offset || select.orders.any?
super
else
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 2cf19c76c5..316b0d6308 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -371,11 +371,11 @@ module ActiveRecord
stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
stmt.table(table)
- stmt.key = table[primary_key]
if joins_values.any?
- @klass.connection.join_to_update(stmt, arel)
+ @klass.connection.join_to_update(stmt, arel, table[primary_key])
else
+ stmt.key = table[primary_key]
stmt.take(arel.limit)
stmt.order(*arel.orders)
stmt.wheres = arel.constraints
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index f343a15317..ba3e16bdb2 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1252,6 +1252,7 @@ class BasicsTest < ActiveRecord::TestCase
original_logger = ActiveRecord::Base.logger
log = StringIO.new
ActiveRecord::Base.logger = ActiveSupport::Logger.new(log)
+ ActiveRecord::Base.logger.level = Logger::DEBUG
ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" }
assert_match(/Quiet/, log.string)
ensure
diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb
index da0d7f5195..783a374116 100644
--- a/activerecord/test/cases/column_definition_test.rb
+++ b/activerecord/test/cases/column_definition_test.rb
@@ -49,6 +49,16 @@ module ActiveRecord
assert_equal "a", varbinary_column.default
end
+ def test_should_be_empty_string_default_for_mysql_binary_data_types
+ type = SqlTypeMetadata.new(type: :binary, sql_type: "binary(1)")
+ binary_column = AbstractMysqlAdapter::Column.new("title", "", type, false)
+ assert_equal "", binary_column.default
+
+ type = SqlTypeMetadata.new(type: :binary, sql_type: "varbinary")
+ varbinary_column = AbstractMysqlAdapter::Column.new("title", "", type, false)
+ assert_equal "", varbinary_column.default
+ end
+
def test_should_not_set_default_for_blob_and_text_data_types
assert_raise ArgumentError do
AbstractMysqlAdapter::Column.new("title", "a", SqlTypeMetadata.new(sql_type: "blob"))
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 1f459a843d..1ba52444c1 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -10,14 +10,14 @@
module Current
thread_mattr_accessor :account
thread_mattr_accessor :user
-
+
def self.reset() self.account = self.user = nil end
end
class ApplicationController < ActiveController::Base
before_action :set_current
after_action { Current.reset }
-
+
private
def set_current
Current.account = Account.find(params[:account_id])
@@ -34,7 +34,7 @@
class Message < ApplicationRecord
has_many :events
after_create :track_created
-
+
private
def track_created
events.create! origin: self, action: :create
@@ -58,9 +58,9 @@
*Yuichiro Kaneko*
-* `ActiveSupport::Cache::Store#namespaced_key`,
- `ActiveSupport::Cache::MemCachedStore#escape_key`, and
- `ActiveSupport::Cache::FileStore#key_file_path`
+* `ActiveSupport::Cache::Store#namespaced_key`,
+ `ActiveSupport::Cache::MemCachedStore#escape_key`, and
+ `ActiveSupport::Cache::FileStore#key_file_path`
are deprecated and replaced with `normalize_key` that now calls `super`.
`ActiveSupport::Cache::LocaleCache#set_cache_value` is deprecated and replaced with `write_cache_value`.
@@ -119,7 +119,7 @@
*Konstantinos Rousis*
-* Handle invalid UTF-8 strings when HTML escaping
+* Handle invalid UTF-8 strings when HTML escaping.
Use `ActiveSupport::Multibyte::Unicode.tidy_bytes` to handle invalid UTF-8
strings in `ERB::Util.unwrapped_html_escape` and `ERB::Util.html_escape_once`.
@@ -160,7 +160,7 @@
* Short-circuit `blank?` on date and time values since they are never blank.
- Fixes #21657
+ Fixes #21657.
*Andrew White*
@@ -198,7 +198,7 @@
* ActiveSupport::HashWithIndifferentAccess `select` and `reject` will now return
enumerator if called without block.
- Fixes #20095
+ Fixes #20095.
*Bernard Potocki*
@@ -212,11 +212,11 @@
*Simon Eskildsen*
-* Fix setting `default_proc` on `HashWithIndifferentAccess#dup`
+* Fix setting `default_proc` on `HashWithIndifferentAccess#dup`.
*Simon Eskildsen*
-* Fix a range of values for parameters of the Time#change
+* Fix a range of values for parameters of the Time#change.
*Nikolay Kondratyev*
@@ -228,7 +228,7 @@
*Kevin Deisz*
* Add a bang version to `ActiveSupport::OrderedOptions` get methods which will raise
- an `KeyError` if the value is `.blank?`
+ an `KeyError` if the value is `.blank?`.
Before:
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 595b0339cc..f741c0bfb8 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -173,7 +173,7 @@ module ActiveSupport
#
# Singular names are not handled correctly:
#
- # classify('calculus') # => "Calculu"
+ # classify('calculus') # => "Calculus"
def classify(table_name)
# strip out any leading schema name
camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))
diff --git a/activesupport/lib/active_support/logger.rb b/activesupport/lib/active_support/logger.rb
index 82117a64d2..520268b244 100644
--- a/activesupport/lib/active_support/logger.rb
+++ b/activesupport/lib/active_support/logger.rb
@@ -46,6 +46,20 @@ module ActiveSupport
super
@formatter = SimpleFormatter.new
@broadcast_messages = true
+ after_initialize if respond_to? :after_initialize
+ end
+
+ def add(severity, message = nil, progname = nil, &block)
+ return true if @logdev.nil? || (severity || UNKNOWN) < level
+ super
+ end
+
+ Logger::Severity.constants.each do |severity|
+ class_eval(<<-EOT, __FILE__, __LINE__ + 1)
+ def #{severity.downcase}? # def debug?
+ Logger::#{severity} >= level # DEBUG >= level
+ end # end
+ EOT
end
# Simple formatter which only displays the message.
diff --git a/activesupport/lib/active_support/logger_silence.rb b/activesupport/lib/active_support/logger_silence.rb
index 7d92256f24..690e5596f7 100644
--- a/activesupport/lib/active_support/logger_silence.rb
+++ b/activesupport/lib/active_support/logger_silence.rb
@@ -1,22 +1,42 @@
require 'active_support/concern'
require 'active_support/core_ext/module/attribute_accessors'
+require 'concurrent'
module LoggerSilence
extend ActiveSupport::Concern
included do
cattr_accessor :silencer
+ attr_reader :local_levels
self.silencer = true
end
+ def after_initialize
+ @local_levels = Concurrent::Map.new(:initial_capacity => 2)
+ end
+
+ def local_log_id
+ Thread.current.__id__
+ end
+
+ def level
+ local_levels[local_log_id] || super
+ end
+
# Silences the logger for the duration of the block.
def silence(temporary_level = Logger::ERROR)
if silencer
begin
- old_logger_level, self.level = level, temporary_level
+ old_local_level = local_levels[local_log_id]
+ local_levels[local_log_id] = temporary_level
+
yield self
ensure
- self.level = old_logger_level
+ if old_local_level
+ local_levels[local_log_id] = old_local_level
+ else
+ local_levels.delete(local_log_id)
+ end
end
else
yield self
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index 191ac0dac5..64d9e71f37 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -47,6 +47,14 @@ module ActiveSupport
# Formats a +number+ into a currency string (e.g., $13.65). You
# can customize the format in the +options+ hash.
#
+ # The currency unit and number formatting of the current locale will be used
+ # unless otherwise specified in the provided options. No currency conversion
+ # is performed. If the user is given a way to change their locale, they will
+ # also be able to change the relative value of the currency displayed with
+ # this helper. If your application will ever support multiple locales, you
+ # may want to specify a constant <tt>:locale</tt> option or consider
+ # using a library capable of currency conversion.
+ #
# ==== Options
#
# * <tt>:locale</tt> - Sets the locale to be used for formatting
diff --git a/activesupport/test/logger_test.rb b/activesupport/test/logger_test.rb
index d2801849ca..a57dc7a241 100644
--- a/activesupport/test/logger_test.rb
+++ b/activesupport/test/logger_test.rb
@@ -3,6 +3,7 @@ require 'multibyte_test_helpers'
require 'stringio'
require 'fileutils'
require 'tempfile'
+require 'concurrent/atomics'
class LoggerTest < ActiveSupport::TestCase
include MultibyteTestHelpers
@@ -113,6 +114,7 @@ class LoggerTest < ActiveSupport::TestCase
end
def test_buffer_multibyte
+ @logger.level = Logger::INFO
@logger.info(UNICODE_STRING)
@logger.info(BYTE_STRING)
assert @output.string.include?(UNICODE_STRING)
@@ -120,14 +122,93 @@ class LoggerTest < ActiveSupport::TestCase
byte_string.force_encoding("ASCII-8BIT")
assert byte_string.include?(BYTE_STRING)
end
-
+
def test_silencing_everything_but_errors
@logger.silence do
@logger.debug "NOT THERE"
@logger.error "THIS IS HERE"
end
-
+
assert !@output.string.include?("NOT THERE")
assert @output.string.include?("THIS IS HERE")
end
+
+ def test_logger_level_per_object_thread_safety
+ logger1 = Logger.new(StringIO.new)
+ logger2 = Logger.new(StringIO.new)
+
+ level = Logger::DEBUG
+ assert_equal level, logger1.level, "Expected level #{level_name(level)}, got #{level_name(logger1.level)}"
+ assert_equal level, logger2.level, "Expected level #{level_name(level)}, got #{level_name(logger2.level)}"
+
+ logger1.level = Logger::ERROR
+ assert_equal level, logger2.level, "Expected level #{level_name(level)}, got #{level_name(logger2.level)}"
+ end
+
+ def test_logger_level_main_thread_safety
+ @logger.level = Logger::INFO
+ assert_level(Logger::INFO)
+
+ latch = Concurrent::CountDownLatch.new
+ latch2 = Concurrent::CountDownLatch.new
+
+ t = Thread.new do
+ latch.wait
+ assert_level(Logger::INFO)
+ latch2.count_down
+ end
+
+ @logger.silence(Logger::ERROR) do
+ assert_level(Logger::ERROR)
+ latch.count_down
+ latch2.wait
+ end
+
+ t.join
+ end
+
+ def test_logger_level_local_thread_safety
+ @logger.level = Logger::INFO
+ assert_level(Logger::INFO)
+
+ thread_1_latch = Concurrent::CountDownLatch.new
+ thread_2_latch = Concurrent::CountDownLatch.new
+
+ threads = (1..2).collect do |thread_number|
+ Thread.new do
+ # force thread 2 to wait until thread 1 is already in @logger.silence
+ thread_2_latch.wait if thread_number == 2
+
+ @logger.silence(Logger::ERROR) do
+ assert_level(Logger::ERROR)
+ @logger.silence(Logger::DEBUG) do
+ # allow thread 2 to finish but hold thread 1
+ if thread_number == 1
+ thread_2_latch.count_down
+ thread_1_latch.wait
+ end
+ assert_level(Logger::DEBUG)
+ end
+ end
+
+ # allow thread 1 to finish
+ assert_level(Logger::INFO)
+ thread_1_latch.count_down if thread_number == 2
+ end
+ end
+
+ threads.each(&:join)
+ assert_level(Logger::INFO)
+ end
+
+ private
+ def level_name(level)
+ ::Logger::Severity.constants.find do |severity|
+ Logger.const_get(severity) == level
+ end.to_s
+ end
+
+ def assert_level(level)
+ assert_equal level, @logger.level, "Expected level #{level_name(level)}, got #{level_name(@logger.level)}"
+ end
end
diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md
index 2fbd75e1c8..3573cecbe0 100644
--- a/guides/source/5_0_release_notes.md
+++ b/guides/source/5_0_release_notes.md
@@ -7,7 +7,7 @@ Highlights in Rails 5.0:
* Action Cable
* Rails API
-* Active Rcord Attributes API
+* Active Record Attributes API
* Test Runner
* Exclusive use of `rails` CLI over Rake
* Sprockets 3
@@ -63,7 +63,7 @@ Please refer to the [Changelog][railties] for detailed changes.
### Removals
-* Removed debugger supprt use byebug instead. `debugger` is not supported by
+* Removed debugger support, use byebug instead. `debugger` is not supported by
Ruby
2.2. ([commit](https://github.com/rails/rails/commit/93559da4826546d07014f8cfa399b64b4a143127))
@@ -284,7 +284,7 @@ Please refer to the [Changelog][action-view] for detailed changes.
directive inside templates.
([Pull Request](https://github.com/rails/rails/pull/20781))
-* Add wildcard matching to explicit dependencies.
+* Added wildcard matching to explicit dependencies.
([Pull Request](https://github.com/rails/rails/pull/20904))
* Make `disable_with` the default behavior for submit tags. Disables the
@@ -329,25 +329,107 @@ Please refer to the [Changelog][active-record] for detailed changes.
### Removals
+* Removed deprecated behavior allowing nested arrays to be passed as query
+ values. ([Pull Request](https://github.com/rails/rails/pull/17919))
+
+* Removed deprecated `ActiveRecord::Tasks::DatabaseTasks#load_schema`. This
+ method was replaced by `ActiveRecord::Tasks::DatabaseTasks#load_schema_for`.
+ ([commit](https://github.com/rails/rails/commit/ad783136d747f73329350b9bb5a5e17c8f8800da))
+
+* Removed deprecated `serialized_attributes`.
+ ([commit](https://github.com/rails/rails/commit/82043ab53cb186d59b1b3be06122861758f814b2))
+
+* Removed deprecated automatic counter caches on `has_many :through`.
+ ([commit](https://github.com/rails/rails/commit/87c8ce340c6c83342df988df247e9035393ed7a0))
+
+* Removed deprecated `sanitize_sql_hash_for_conditions`.
+ ([commit](https://github.com/rails/rails/commit/3a59dd212315ebb9bae8338b98af259ac00bbef3))
+
+* Removed deprecated `Reflection#source_macro`.
+ ([commit](https://github.com/rails/rails/commit/ede8c199a85cfbb6457d5630ec1e285e5ec49313))
+
+* Removed deprecated `symbolized_base_class` and `symbolized_sti_name`.
+ ([commit](https://github.com/rails/rails/commit/9013e28e52eba3a6ffcede26f85df48d264b8951))
+
+* Removed deprecated `ActiveRecord::Base.disable_implicit_join_references=`.
+ ([commit](https://github.com/rails/rails/commit/0fbd1fc888ffb8cbe1191193bf86933110693dfc))
+
+* Removed deprecated access to connection specification using a string accessor.
+ ([commit](https://github.com/rails/rails/commit/efdc20f36ccc37afbb2705eb9acca76dd8aabd4f))
+
+* Removed deprecated support to preload instance-dependent associations.
+ ([commit](https://github.com/rails/rails/commit/4ed97979d14c5e92eb212b1a629da0a214084078))
+
+* Removed deprecated support for PostgreSQL ranges with exclusive lower bounds.
+ ([commit](https://github.com/rails/rails/commit/a076256d63f64d194b8f634890527a5ed2651115))
+
+* Removed deprecation when modifying a relation with cached Arel.
+ This raises an `ImmutableRelation` error instead.
+ ([commit](https://github.com/rails/rails/commit/3ae98181433dda1b5e19910e107494762512a86c))
+
+* Removed `ActiveRecord::Serialization::XmlSerializer` from core. This feature
+ has been extracted into the
+ [activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml)
+ gem. ([Pull Request](https://github.com/rails/rails/pull/21161))
+
+* Removed support for the legacy `mysql` database adapter from core. It will
+ live on in a separate gem for now, but most users should just use `mysql2`.
+
+* Removed support for the `protected_attributes` gem.
+ ([commit](https://github.com/rails/rails/commit/f4fbc0301021f13ae05c8e941c8efc4ae351fdf9))
+
### Deprecations
+* Deprecated passing a class as a value in a query. Users should pass strings
+ instead. ([Pull Request](https://github.com/rails/rails/pull/17916))
+
* Deprecated returning `false` as a way to halt Active Record callback
chains. The recommended way is to
`throw(:abort)`. ([Pull Request](https://github.com/rails/rails/pull/17227))
+* Deprecated `ActiveRecord::Base.errors_in_transactional_callbacks=`.
+ ([commit](https://github.com/rails/rails/commit/07d3d402341e81ada0214f2cb2be1da69eadfe72))
+
+* Deprecated passing of `start` value to `find_in_batches` and `find_each`
+ in favour of `begin_at` value.
+ ([Pull Request](https://github.com/rails/rails/pull/18961))
+
+* Deprecated `Relation#uniq` use `Relation#distinct` instead.
+ ([commit](https://github.com/rails/rails/commit/adfab2dcf4003ca564d78d4425566dd2d9cd8b4f))
+
+* Deprecated the PostgreSQL `:point` type in favor of a new one which will return
+ `Point` objects instead of an `Array`
+ ([Pull Request](https://github.com/rails/rails/pull/20448))
+
+* Deprecated force association reload by passing a truthy argument to
+ association method.
+ ([Pull Request](https://github.com/rails/rails/pull/20888))
+
+* Deprecated the keys for association `restrict_dependent_destroy` errors in favor
+ of new key names.
+ ([Pull Request](https://github.com/rails/rails/pull/20668))
+
* Synchronize behavior of `#tables`.
([Pull Request](https://github.com/rails/rails/pull/21601))
+* Deprecated `SchemaCache#tables`, `SchemaCache#table_exists?` and
+ `SchemaCache#clear_table_cache!` in favor of their new data source
+ counterparts.
+ ([Pull Request](https://github.com/rails/rails/pull/21715))
+
* Deprecated `connection.tables` on the SQLite3 and MySQL adapters.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
* Deprecated passing arguments to `#tables` - the `#tables` method of some
adapters (mysql2, sqlite3) would return both tables and views while others
(postgresql) just return tables. To make their behavior consistent,
`#tables` will return only tables in the future.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
* Deprecated `table_exists?` - The `#table_exists?` method would check both
tables and views. To make their behavior consistent with `#tables`,
`#table_exists?` will check only tables in the future.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
### Notable changes
@@ -370,6 +452,89 @@ Please refer to the [Changelog][active-record] for detailed changes.
([Pull Request](https://github.com/rails/rails/pull/18937)) - Deprecate
`required` option in favor of `optional` for `belongs_to`
+* Changed the default `null` value for `timestamps` to `false`.
+ ([commit](https://github.com/rails/rails/commit/a939506f297b667291480f26fa32a373a18ae06a))
+
+* Added `ActiveRecord::SecureToken` in order to encapsulate generation of
+ unique tokens for attributes in a model using `SecureRandom`.
+ ([Pull Request](https://github.com/rails/rails/pull/18217))
+
+* Added `:if_exists` option for `drop_table`.
+ ([Pull Request](https://github.com/rails/rails/pull/18597))
+
+* Added `ActiveRecord::Base#accessed_fields`, which can be used to quickly
+ discover which fields were read from a model when you are looking to only
+ select the data you need from the database.
+ ([commit](https://github.com/rails/rails/commit/be9b68038e83a617eb38c26147659162e4ac3d2c))
+
+* Added the `#or` method on `ActiveRecord::Relation`, allowing use of the OR
+ operator to combine WHERE or HAVING clauses.
+ ([commit](https://github.com/rails/rails/commit/b0b37942d729b6bdcd2e3178eda7fa1de203b3d0))
+
+* Added `:time` option added for `#touch`.
+ ([Pull Request](https://github.com/rails/rails/pull/18956))
+
+* Added `ActiveRecord::Base.suppress` to prevent the receiver from being saved
+ during the given block.
+ ([Pull Request](https://github.com/rails/rails/pull/18910))
+
+* `belongs_to` will now trigger a validation error by default if the
+ association is not present. You can turn this off on a per-association basis
+ with `optional: true`.
+ ([Pull Request](https://github.com/rails/rails/pull/18937))
+
+* Added `config.active_record.dump_schemas` to configure the behavior of
+ `db:structure:dump`.
+ ([Pull Request](https://github.com/rails/rails/pull/19347))
+
+* Added `config.active_record.warn_on_records_fetched_greater_than` option.
+ ([Pull Request](https://github.com/rails/rails/pull/18846))
+
+* Added `cache_key` to `ActiveRecord::Relation`.
+ ([Pull Request](https://github.com/rails/rails/pull/20884))
+
+* Added a native JSON data type support in MySQL.
+ ([Pull Request](https://github.com/rails/rails/pull/21110))
+
+* Added support for dropping indexes concurrently in PostgreSQL.
+ ([Pull Request](https://github.com/rails/rails/pull/21317))
+
+* Added `#views` and `#view_exists?` methods on connection adapters.
+ ([Pull Request](https://github.com/rails/rails/pull/21609))
+
+* Added `ActiveRecord::Base.ignored_columns` to make some columns
+ invisible from Active Record.
+ ([Pull Request](https://github.com/rails/rails/pull/21720))
+
+* Added `connection.data_sources` and `connection.data_source_exists?`.
+ These methods determine what relations can be used to back Active Record
+ models (usually tables and views).
+ ([Pull Request](https://github.com/rails/rails/pull/21715))
+
+* Allow fixtures files to set the model class in the YAML file itself.
+ ([Pull Request](https://github.com/rails/rails/pull/20574))
+
+* Added ability to default to `uuid` as primary key when generating database
+ migrations. ([Pull Request](https://github.com/rails/rails/pull/21762))
+
+* Added `ActiveRecord::Relation#left_joins` and
+ `ActiveRecord::Relation#left_outer_joins`.
+ ([Pull Request](https://github.com/rails/rails/pull/12071))
+
+* Added `after_{create,update,delete}_commit` callbacks.
+ ([Pull Request](https://github.com/rails/rails/pull/22516))
+
+* Version the API presented to migration classes, so we can change parameter
+ defaults without breaking existing migrations, or forcing them to be
+ rewritten through a deprecation cycle.
+ ([Pull Request](https://github.com/rails/rails/pull/21538))
+
+* `ApplicationRecord` is a new superclass for all app models, analogous to app
+ controllers subclassing `ApplicationController` instead of
+ `ActionController::Base`. This gives apps a single spot to configure app-wide
+ model behavior.
+ ([Pull Request](https://github.com/rails/rails/pull/22567))
+
Active Model
------------
@@ -378,6 +543,10 @@ Please refer to the [Changelog][active-model] for detailed changes.
### Removals
+* Removed deprecated `ActiveModel::Dirty#reset_#{attribute}` and
+ `ActiveModel::Dirty#reset_changes`.
+ ([Pull Request](https://github.com/rails/rails/commit/37175a24bd508e2983247ec5d011d57df836c743))
+
* Removed XML serialization. This feature has been extracted into the
[activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml) gem.
([Pull Request](https://github.com/rails/rails/pull/21161))
@@ -388,8 +557,32 @@ Please refer to the [Changelog][active-model] for detailed changes.
`ActiveModel::Validations` callback chains. The recommended way is to
`throw(:abort)`. ([Pull Request](https://github.com/rails/rails/pull/17227))
+* Deprecated `ActiveModel::Errors#get`, `ActiveModel::Errors#set` and
+ `ActiveModel::Errors#[]=` methods that have inconsistent behavior.
+ ([Pull Request](https://github.com/rails/rails/pull/18634))
+
+* Deprecated the `:tokenizer` option for `validates_length_of`, in favor of
+ plain Ruby.
+ ([Pull Request](https://github.com/rails/rails/pull/19585))
+
+* Deprecated `ActiveModel::Errors#add_on_empty` and `ActiveModel::Errors#add_on_blank`
+ with no replacement.
+ ([Pull Request](https://github.com/rails/rails/pull/18996))
+
### Notable changes
+* Added `ActiveModel::Errors#details` to determine what validator has failed.
+ ([Pull Request](https://github.com/rails/rails/pull/18322))
+
+* Extracted `ActiveRecord::AttributeAssignment` to `ActiveModel::AttributeAssignment`
+ allowing to use it for any object as an includable module.
+ ([Pull Request](https://github.com/rails/rails/pull/10776))
+
+* Added `ActiveModel::Dirty#[attr_name]_previously_changed?` and
+ `ActiveModel::Dirty#[attr_name]_previous_change` to improve access
+ to recorded changes after the model has been saved.
+ ([Pull Request](https://github.com/rails/rails/pull/19847))
+
* Validate multiple contexts on `valid?` and `invalid?` at once.
([Pull Request](https://github.com/rails/rails/pull/21069))
@@ -399,11 +592,24 @@ Active Job
Please refer to the [Changelog][active-job] for detailed changes.
-### Removals
+### Notable changes
-### Deprecations
+* `ActiveJob::Base.deserialize` delegates to the job class. this allows jobs
+ to attach arbitrary metadata when they get serialized and read it back when
+ they get performed.
+ ([Pull Request](https://github.com/rails/rails/pull/18260))
-### Notable changes
+* A generated job now inherits from `app/jobs/application_job.rb` by default.
+ ([Pull Request](https://github.com/rails/rails/pull/19034))
+
+* Allow `DelayedJob`, `Sidekiq`, `qu`, and `que` to report the job id back to
+ `ActiveJob::Base` as `provider_job_id`.
+ ([Pull Request](https://github.com/rails/rails/pull/20064),
+ [Pull Request](https://github.com/rails/rails/pull/20056))
+
+* Implement a simple `AsyncJob` processor and associated `AsyncAdapter` that
+ queue jobs to a `concurrent-ruby` thread pool.
+ ([Pull Request](https://github.com/rails/rails/pull/21257))
Active Support
@@ -413,20 +619,135 @@ Please refer to the [Changelog][active-support] for detailed changes.
### Removals
+* Removed deprecated `ActiveSupport::JSON::Encoding::CircularReferenceError`.
+ ([commit](https://github.com/rails/rails/commit/d6e06ea8275cdc3f126f926ed9b5349fde374b10))
+
+* Removed deprecated methods `ActiveSupport::JSON::Encoding.encode_big_decimal_as_string=`
+ and `ActiveSupport::JSON::Encoding.encode_big_decimal_as_string`.
+ ([commit](https://github.com/rails/rails/commit/c8019c0611791b2716c6bed48ef8dcb177b7869c))
+
+* Removed deprecated `ActiveSupport::SafeBuffer#prepend`.
+ ([commit](https://github.com/rails/rails/commit/e1c8b9f688c56aaedac9466a4343df955b4a67ec))
+
+* Removed deprecated methods from `Kernel`. `silence_stderr`, `silence_stream`,
+ `capture` and `quietly`.
+ ([commit](https://github.com/rails/rails/commit/481e49c64f790e46f4aff3ed539ed227d2eb46cb))
+
+* Removed deprecated `active_support/core_ext/big_decimal/yaml_conversions`
+ file.
+ ([commit](https://github.com/rails/rails/commit/98ea19925d6db642731741c3b91bd085fac92241))
+
+* Removed deprecated methods `ActiveSupport::Cache::Store.instrument` and
+ `ActiveSupport::Cache::Store.instrument=`.
+ ([commit](https://github.com/rails/rails/commit/a3ce6ca30ed0e77496c63781af596b149687b6d7))
+
+* Removed deprecated `Class#superclass_delegating_accessor`.
+ Use `Class#class_attribute` instead.
+ ([Pull Request](https://github.com/rails/rails/pull/16938))
+
+* Removed deprecated `ThreadSafe::Cache`. Use `Concurrent::Map` instead.
+ ([Pull Request](https://github.com/rails/rails/pull/21679))
+
### Deprecations
-* Replace `ActiveSupport::Concurrency::Latch` with
+* Deprecated `MissingSourceFile` in favor of `LoadError`.
+ ([commit](https://github.com/rails/rails/commit/734d97d2))
+
+* Deprecated `alias_method_chain` in favour of `Module#prepend` introduced in
+ Ruby 2.0.
+ ([Pull Request](https://github.com/rails/rails/pull/19434))
+
+* Deprecated `ActiveSupport::Concurrency::Latch` in favor of
`Concurrent::CountDownLatch` from concurrent-ruby.
([Pull Request](https://github.com/rails/rails/pull/20866))
+* Deprecated `:prefix` option of `number_to_human_size` with no replacement.
+ ([Pull Request](https://github.com/rails/rails/pull/21191))
+
+* Deprecated `Module#qualified_const_` in favour of the builtin
+ `Module#const_` methods.
+ ([Pull Request](https://github.com/rails/rails/pull/17845))
+
+* Deprecated passing string to define callback.
+ ([Pull Request](https://github.com/rails/rails/pull/22598))
+
+* Deprecated `ActiveSupport::Cache::Store#namespaced_key`,
+ `ActiveSupport::Cache::MemCachedStore#escape_key`, and
+ `ActiveSupport::Cache::FileStore#key_file_path`.
+ Use `normalize_key` instead.
+
+ Deprecated `ActiveSupport::Cache::LocaleCache#set_cache_value` in favor of `write_cache_value`.
+ ([Pull Request](https://github.com/rails/rails/pull/22215))
+
### Notable changes
+* Added `#verified` and `#valid_message?` methods to
+ `ActiveSupport::MessageVerifier`.
+ ([Pull Request](https://github.com/rails/rails/pull/17727))
+
+* Changed the way in which callback chains can be halted. The preferred method
+ to halt a callback chain from now on is to explicitly `throw(:abort)`.
+ ([Pull Request](https://github.com/rails/rails/pull/17227))
+
* New config option
`config.active_support.halt_callback_chains_on_return_false` to specify
whether ActiveRecord, ActiveModel and ActiveModel::Validations callback
chains can be halted by returning `false` in a 'before' callback.
([Pull Request](https://github.com/rails/rails/pull/17227))
+* Changed the default test order from `:sorted` to `:random`.
+ ([commit](https://github.com/rails/rails/commit/5f777e4b5ee2e3e8e6fd0e2a208ec2a4d25a960d))
+
+* Added `#on_weekend?`, `#next_weekday`, `#prev_weekday` methods to `Date`,
+ `Time`, and `DateTime`.
+ ([Pull Request](https://github.com/rails/rails/pull/18335))
+
+* Added `same_time` option to `#next_week` and `#prev_week` for `Date`, `Time`,
+ and `DateTime`.
+ ([Pull Request](https://github.com/rails/rails/pull/18335))
+
+* Added `#prev_day` and `#next_day` counterparts to `#yesterday` and
+ `#tomorrow` for `Date`, `Time`, and `DateTime`.
+ ([Pull Request](httpshttps://github.com/rails/rails/pull/18335))
+
+* Added `SecureRandom.base58` for generation of random base58 strings.
+ ([commit](https://github.com/rails/rails/commit/b1093977110f18ae0cafe56c3d99fc22a7d54d1b))
+
+* Added `file_fixture` to `ActiveSupport::TestCase`.
+ It provides a simple mechanism to access sample files in your test cases.
+ ([Pull Request](https://github.com/rails/rails/pull/18658))
+
+* Added `#without` on `Enumerable` and `Array` to return a copy of an
+ enumerable without the specified elements.
+ ([Pull Request](https://github.com/rails/rails/pull/19157))
+
+* Added `ActiveSupport::ArrayInquirer` and `Array#inquiry`.
+ ([Pull Request](https://github.com/rails/rails/pull/18939))
+
+* Added `ActiveSupport::TimeZone#strptime` to allow parsing times as if
+ from a given timezone.
+ ([commit](https://github.com/rails/rails/commit/a5e507fa0b8180c3d97458a9b86c195e9857d8f6))
+
+* Added `Integer#positive?` and `Integer#negative?` query methods
+ in the vein of `Fixnum#zero?`.
+ ([commit](https://github.com/rails/rails/commit/e54277a45da3c86fecdfa930663d7692fd083daa))
+
+* Added a bang version to `ActiveSupport::OrderedOptions` get methods which will raise
+ an `KeyError` if the value is `.blank?`.
+ ([Pull Request](https://github.com/rails/rails/pull/20208))
+
+* Added `Time.days_in_year` to return the number of days in the given year, or the
+ current year if no argument is provided.
+ ([commit](https://github.com/rails/rails/commit/2f4f4d2cf1e4c5a442459fc250daf66186d110fa))
+
+* Added an evented file watcher to asynchronously detect changes in the
+ application source code, routes, locales, etc.
+ ([Pull Request](https://github.com/rails/rails/pull/22254))
+
+* Added thread_m/cattr_accessor/reader/writer suite of methods for declaring
+ class and module variables that live per-thread.
+ ([Pull Request](https://github.com/rails/rails/pull/22630))
+
Credits
-------
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index d9037674ca..543937f8e5 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -599,7 +599,7 @@ This would add something like "Process data files (0.34523)" to the log, which y
#### cache
-A method for caching fragments of a view rather than an entire action or page. This technique is useful caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See `ActionController::Caching::Fragments` for more information.
+A method for caching fragments of a view rather than an entire action or page. This technique is useful for caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See `ActionController::Caching::Fragments` for more information.
```erb
<% cache do %>
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 47acff7c3f..81e406ae2e 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -104,7 +104,7 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
you don't want shown in the logs, such as passwords or credit card
numbers. New applications filter out passwords by adding the following `config.filter_parameters+=[:password]` in `config/initializers/filter_parameter_logging.rb`.
-* `config.force_ssl` forces all requests to be under HTTPS protocol by using `ActionDispatch::SSL` middleware.
+* `config.force_ssl` forces all requests to be served over HTTPS by using the `ActionDispatch::SSL` middleware. This can be configured by setting `config.ssl_options` - see the [ActionDispatch::SSL documentation](http://edgeapi.rubyonrails.org/classes/ActionDispatch/SSL.html) for details.
* `config.log_formatter` defines the formatter of the Rails logger. This option defaults to an instance of `ActiveSupport::Logger::SimpleFormatter` for all modes except production, where it defaults to `Logger::Formatter`.
@@ -198,7 +198,7 @@ The full set of methods that can be used in this block are as follows:
Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
-* `ActionDispatch::SSL` forces every request to be under HTTPS protocol. Will be available if `config.force_ssl` is set to `true`. Options passed to this can be configured by using `config.ssl_options`.
+* `ActionDispatch::SSL` forces every request to be served using HTTPS. Enabled if `config.force_ssl` is set to `true`. Options passed to this can be configured by setting `config.ssl_options`.
* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.public_file_server.enabled` is `false`. Set `config.public_file_server.index_name` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.public_file_server.index_name` to `"main"`.
* `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time. Only enabled when `config.cache_classes` is `false`.
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 2b1254f7a0..9401132500 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -392,7 +392,7 @@ The comments resource here will have the following routes generated for it:
### Routing concerns
-Routing Concerns allows you to declare common routes that can be reused inside other resources and routes. To define a concern:
+Routing concerns allow you to declare common routes that can be reused inside other resources and routes. To define a concern:
```ruby
concern :commentable do
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 2f18619e30..064b109a6f 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -75,7 +75,7 @@ module Rails
class_option :edge, type: :boolean, default: false,
desc: "Setup the #{name} with Gemfile pointing to Rails repository"
- class_option :rc, type: :string, default: false,
+ class_option :rc, type: :string, default: nil,
desc: "Path to file containing extra configuration options for rails command"
class_option :no_rc, type: :boolean, default: false,
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
index 40c831ec58..78f4530514 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
@@ -1,5 +1,5 @@
# Be sure to restart your server when you modify this file.
-# Require `belongs_to` associations by default. This is a new Rails 5.0 default,
+# Require `belongs_to` associations by default. This is a new Rails 5.0 default,
# so introduced as a config to ensure apps made with earlier versions of Rails aren't affected when upgrading.
Rails.application.config.active_record.belongs_to_required_by_default = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
index 43510c244b..0b718aa1c6 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
@@ -1,5 +1,5 @@
# Be sure to restart your server when you modify this file.
-# Do not halt callback chains when a callback returns false. This is a new Rails 5.0 default,
+# Do not halt callback chains when a callback returns false. This is a new Rails 5.0 default,
# so introduced as a config to ensure apps made with earlier versions of Rails aren't affected when upgrading.
ActiveSupport.halt_callback_chains_on_return_false = false
diff --git a/railties/lib/rails/generators/rails/plugin/templates/README.md b/railties/lib/rails/generators/rails/plugin/templates/README.md
index 61ad1ed36a..9d2b74416e 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/README.md
+++ b/railties/lib/rails/generators/rails/plugin/templates/README.md
@@ -1,3 +1,28 @@
# <%= camelized_modules %>
+Short description and motivation.
-This project rocks and uses MIT-LICENSE.
+## Usage
+How to use my plugin.
+
+## Installation
+Add this line to your application's Gemfile:
+
+```ruby
+gem '<%= name %>'
+```
+
+And then execute:
+```bash
+$ bundle
+```
+
+Or install it yourself as:
+```bash
+$ gem install <%= name %>
+```
+
+## Contributing
+Contribution directions go here.
+
+## License
+The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb
index d39d2f32bf..d4ab2ada66 100644
--- a/railties/lib/rails/test_unit/minitest_plugin.rb
+++ b/railties/lib/rails/test_unit/minitest_plugin.rb
@@ -3,16 +3,13 @@ require "rails/test_unit/reporter"
require "rails/test_unit/test_requirer"
module Minitest
- mattr_accessor(:hide_aggregated_results) { false }
-
- module AggregatedResultSuppresion
+ class SuppressedSummaryReporter < SummaryReporter
+ # Disable extra failure output after a run if output is inline.
def aggregated_results
- super unless Minitest.hide_aggregated_results
+ super unless options[:output_inline]
end
end
- SummaryReporter.prepend AggregatedResultSuppresion
-
def self.plugin_rails_options(opts, options)
executable = ::Rails::TestUnitReporter.executable
opts.separator ""
@@ -49,6 +46,12 @@ module Minitest
options[:fail_fast] = true
end
+ opts.on("-c", "--[no-]color",
+ "Enable color in the output") do |value|
+ options[:color] = value
+ end
+
+ options[:color] = true
options[:output_inline] = true
options[:patterns] = opts.order!
end
@@ -77,9 +80,8 @@ module Minitest
Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner)
end
- # Disable the extra failure output after a run, unless output is deferred.
- self.hide_aggregated_results = options[:output_inline]
-
+ self.reporter.reporters.clear # Replace progress reporter for colors.
+ self.reporter << SuppressedSummaryReporter.new(options[:io], options)
self.reporter << ::Rails::TestUnitReporter.new(options[:io], options)
end
diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb
index 695c67756b..73b8d7d27b 100644
--- a/railties/lib/rails/test_unit/reporter.rb
+++ b/railties/lib/rails/test_unit/reporter.rb
@@ -9,10 +9,16 @@ module Rails
def record(result)
super
+ if options[:verbose]
+ io.puts color_output(format_line(result), by: result)
+ else
+ io.print color_output(result.result_code, by: result)
+ end
+
if output_inline? && result.failure && (!result.skipped? || options[:verbose])
io.puts
io.puts
- io.puts format_failures(result)
+ io.puts format_failures(result).map { |line| color_output(line, by: result) }
io.puts
io.puts format_rerun_snippet(result)
io.puts
@@ -56,6 +62,10 @@ module Rails
options[:fail_fast]
end
+ def format_line(result)
+ "%s#%s = %.2f s = %s" % [result.class, result.name, result.time, result.result_code]
+ end
+
def format_failures(result)
result.failures.map do |failure|
"#{failure.result_label}:\n#{result.class}##{result.name}:\n#{failure.message}\n"
@@ -76,5 +86,25 @@ module Rails
def app_root
@app_root ||= defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
end
+
+ def colored_output?
+ options[:color] && io.respond_to?(:tty?) && io.tty?
+ end
+
+ codes = { red: 31, green: 32, yellow: 33 }
+ COLOR_BY_RESULT_CODE = {
+ "." => codes[:green],
+ "E" => codes[:red],
+ "F" => codes[:red],
+ "S" => codes[:yellow]
+ }
+
+ def color_output(string, by:)
+ if colored_output?
+ "\e[#{COLOR_BY_RESULT_CODE[by.result_code]}m#{string}\e[0m"
+ else
+ string
+ end
+ end
end
end
diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb
index 3ff7cd18cd..2d08d4ec30 100644
--- a/railties/test/test_unit/reporter_test.rb
+++ b/railties/test/test_unit/reporter_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'rails/test_unit/reporter'
+require 'minitest/mock'
class TestUnitReporterTest < ActiveSupport::TestCase
class ExampleTest < Minitest::Test
@@ -61,7 +62,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
@reporter.record(failed_test)
@reporter.report
- expect = %r{\A\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot:\nboo\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
+ expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot:\nboo\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
assert_match expect, @output.string
end
@@ -69,7 +70,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
@reporter.record(errored_test)
@reporter.report
- expect = %r{\A\n\nError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n No backtrace\n\nbin/rails test .*test/test_unit/reporter_test.rb:6\n\n\z}
+ expect = %r{\AE\n\nError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n No backtrace\n\nbin/rails test .*test/test_unit/reporter_test.rb:\d+\n\n\z}
assert_match expect, @output.string
end
@@ -78,7 +79,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
verbose.record(skipped_test)
verbose.report
- expect = %r{\A\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
+ expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
assert_match expect, @output.string
end
@@ -113,6 +114,36 @@ class TestUnitReporterTest < ActiveSupport::TestCase
assert_no_match 'Failed tests:', @output.string
end
+ test "outputs colored passing results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(passing_test)
+
+ expect = %r{\e\[32m\.\e\[0m}
+ assert_match expect, @output.string
+ end
+ end
+
+ test "outputs colored skipped results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(skipped_test)
+
+ expect = %r{\e\[33mS\e\[0m}
+ assert_match expect, @output.string
+ end
+ end
+
+ test "outputs colored failed results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(errored_test)
+
+ expected = %r{\e\[31mE\e\[0m\n\n\e\[31mError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n No backtrace\n\e\[0m}
+ assert_match expected, @output.string
+ end
+ end
+
private
def assert_rerun_snippet_count(snippet_count)
assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size
@@ -145,6 +176,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
rescue Minitest::Assertion => e
e
end
+ st.time = 10
st
end
end