aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activemodel/lib/active_model/type.rb2
-rw-r--r--activerecord/lib/active_record/attributes.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb8
-rw-r--r--activerecord/lib/active_record/log_subscriber.rb31
-rw-r--r--activerecord/test/cases/query_cache_test.rb36
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb4
-rw-r--r--activesupport/test/evented_file_update_checker_test.rb2
-rw-r--r--activesupport/test/file_update_checker_shared_tests.rb18
-rw-r--r--guides/source/active_record_migrations.md18
-rw-r--r--guides/source/active_support_core_extensions.md8
10 files changed, 99 insertions, 34 deletions
diff --git a/activemodel/lib/active_model/type.rb b/activemodel/lib/active_model/type.rb
index 313f17830f..0d3349e236 100644
--- a/activemodel/lib/active_model/type.rb
+++ b/activemodel/lib/active_model/type.rb
@@ -27,7 +27,7 @@ module ActiveModel
delegate :add_modifier, to: :registry
# Add a new type to the registry, allowing it to be referenced as a
- # symbol by ActiveModel::Attributes::ClassMethods#attribute. If your
+ # symbol by ActiveRecord::Attributes::ClassMethods#attribute. If your
# type is only meant to be used with a specific database adapter, you can
# do so by passing +adapter: :postgresql+. If your type has the same
# name as a native type for the current adapter, an exception will be
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index 4b92e5835f..dcbfca1c04 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -116,7 +116,7 @@ module ActiveRecord
# Users may also define their own custom types, as long as they respond
# to the methods defined on the value type. The method +deserialize+ or
# +cast+ will be called on your type object, with raw input from the
- # database or from your controllers. See ActiveRecord::Type::Value for the
+ # database or from your controllers. See ActiveModel::Type::Value for the
# expected API. It is recommended that your type objects inherit from an
# existing type, or from ActiveRecord::Type::Value
#
@@ -143,7 +143,7 @@ module ActiveRecord
# store_listing.price_in_cents # => 1000
#
# For more details on creating custom types, see the documentation for
- # ActiveRecord::Type::Value. For more details on registering your types
+ # ActiveModel::Type::Value. For more details on registering your types
# to be referenced by a symbol, see ActiveRecord::Type.register. You can
# also pass a type object directly, in place of a symbol.
#
@@ -190,7 +190,7 @@ module ActiveRecord
# The type of an attribute is given the opportunity to change how dirty
# tracking is performed. The methods +changed?+ and +changed_in_place?+
# will be called from ActiveModel::Dirty. See the documentation for those
- # methods in ActiveRecord::Type::Value for more details.
+ # methods in ActiveModel::Type::Value for more details.
def attribute(name, cast_type, **options)
name = name.to_s
reload_schema_from_cache
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index ffde4f2c93..83d1d7cd01 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -475,7 +475,7 @@ module ActiveRecord
# Checks to see if a column exists.
#
- # t.string(:name) unless t.column_exists?(:name, :string)
+ # t.string(:name) unless t.column_exists?(:name, :string)
#
# See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
def column_exists?(column_name, type = nil, options = {})
@@ -496,9 +496,9 @@ module ActiveRecord
# Checks to see if an index exists.
#
- # unless t.index_exists?(:branch_id)
- # t.index(:branch_id)
- # end
+ # unless t.index_exists?(:branch_id)
+ # t.index(:branch_id)
+ # end
#
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
def index_exists?(column_name, options = {})
diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb
index ad71c6cde8..4b8d8d9105 100644
--- a/activerecord/lib/active_record/log_subscriber.rb
+++ b/activerecord/lib/active_record/log_subscriber.rb
@@ -15,16 +15,6 @@ module ActiveRecord
rt
end
- def render_bind(attr, type_casted_value)
- value = if attr.type.binary? && attr.value
- "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
- else
- type_casted_value
- end
-
- [attr.name, value]
- end
-
def sql(event)
self.class.runtime += event.duration
return unless logger.debug?
@@ -39,7 +29,8 @@ module ActiveRecord
binds = nil
unless (payload[:binds] || []).empty?
- binds = " " + payload[:binds].zip(payload[:type_casted_binds]).map { |attr, value|
+ casted_params = type_casted_binds(payload[:binds], payload[:type_casted_binds])
+ binds = " " + payload[:binds].zip(casted_params).map { |attr, value|
render_bind(attr, value)
}.inspect
end
@@ -52,6 +43,20 @@ module ActiveRecord
private
+ def type_casted_binds(binds, casted_binds)
+ casted_binds || binds.map { |attr| type_cast attr.value_for_database }
+ end
+
+ def render_bind(attr, type_casted_value)
+ value = if attr.type.binary? && attr.value
+ "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
+ else
+ type_casted_value
+ end
+
+ [attr.name, value]
+ end
+
def colorize_payload_name(name, payload_name)
if payload_name.blank? || payload_name == "SQL" # SQL vs Model Load/Exists
color(name, MAGENTA, true)
@@ -84,6 +89,10 @@ module ActiveRecord
def logger
ActiveRecord::Base.logger
end
+
+ def type_cast(value)
+ ActiveRecord::Base.connection.type_cast(value)
+ end
end
end
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 16cf2bd2d0..4cd258695d 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -10,9 +10,30 @@ class QueryCacheTest < ActiveRecord::TestCase
fixtures :tasks, :topics, :categories, :posts, :categories_posts
- teardown do
+ class ShouldNotHaveExceptionsLogger < ActiveRecord::LogSubscriber
+ attr_reader :logger
+
+ def initialize
+ super
+ @logger = ::Logger.new File::NULL
+ @exception = false
+ end
+
+ def exception?
+ @exception
+ end
+
+ def sql(event)
+ super
+ rescue
+ @exception = true
+ end
+ end
+
+ def teardown
Task.connection.clear_query_cache
ActiveRecord::Base.connection.disable_query_cache!
+ super
end
def test_exceptional_middleware_clears_and_disables_cache_on_error
@@ -121,6 +142,19 @@ class QueryCacheTest < ActiveRecord::TestCase
end
end
+ def test_cache_does_not_raise_exceptions
+ logger = ShouldNotHaveExceptionsLogger.new
+ subscriber = ActiveSupport::Notifications.subscribe "sql.active_record", logger
+
+ ActiveRecord::Base.cache do
+ assert_queries(1) { Task.find(1); Task.find(1) }
+ end
+
+ assert_not_predicate logger, :exception?
+ ensure
+ ActiveSupport::Notifications.unsubscribe subscriber
+ end
+
def test_cache_is_flat
Task.cache do
assert_queries(1) { Topic.find(1); Topic.find(1); }
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
index b1e6fe71e0..1e82b4acc2 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
@@ -34,7 +34,7 @@ class Module
# end
#
# Current.new.user # => NoMethodError
- def thread_mattr_reader(*syms)
+ def thread_mattr_reader(*syms) # :nodoc:
options = syms.extract_options!
syms.each do |sym|
@@ -77,7 +77,7 @@ class Module
# end
#
# Current.new.user = "DHH" # => NoMethodError
- def thread_mattr_writer(*syms)
+ def thread_mattr_writer(*syms) # :nodoc:
options = syms.extract_options!
syms.each do |sym|
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
diff --git a/activesupport/test/evented_file_update_checker_test.rb b/activesupport/test/evented_file_update_checker_test.rb
index cc47318974..77d8dcb0f8 100644
--- a/activesupport/test/evented_file_update_checker_test.rb
+++ b/activesupport/test/evented_file_update_checker_test.rb
@@ -36,6 +36,8 @@ class EventedFileUpdateCheckerTest < ActiveSupport::TestCase
end
test "notifies forked processes" do
+ jruby_skip "Forking not available on JRuby"
+
FileUtils.touch(tmpfiles)
checker = new_checker(tmpfiles) {}
diff --git a/activesupport/test/file_update_checker_shared_tests.rb b/activesupport/test/file_update_checker_shared_tests.rb
index cd6a58e840..48cd387196 100644
--- a/activesupport/test/file_update_checker_shared_tests.rb
+++ b/activesupport/test/file_update_checker_shared_tests.rb
@@ -49,6 +49,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker(tmpfiles) { i += 1 }
touch(tmpfiles)
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -62,6 +63,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker(tmpfiles) { i += 1 }
touch(tmpfiles)
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -75,6 +77,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker(tmpfiles) { i += 1 }
rm_f(tmpfiles)
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -87,6 +90,7 @@ module FileUpdateCheckerSharedTests
assert !checker.updated?
touch(tmpfiles)
+ wait
assert checker.updated?
end
@@ -100,6 +104,7 @@ module FileUpdateCheckerSharedTests
assert !checker.updated?
touch(tmpfiles)
+ wait
assert checker.updated?
end
@@ -113,6 +118,7 @@ module FileUpdateCheckerSharedTests
assert !checker.updated?
rm_f(tmpfiles)
+ wait
assert checker.updated?
end
@@ -129,6 +135,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker(tmpfiles) { i += 1 }
touch(tmpfiles[1..-1])
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -145,6 +152,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker(tmpfiles) { i += 1 }
touch(tmpfiles[1..-1])
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -157,6 +165,7 @@ module FileUpdateCheckerSharedTests
assert !checker.updated?
touch(tmpfiles)
+ wait
assert checker.updated?
checker.execute
@@ -169,6 +178,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker([], tmpdir => :rb) { i += 1 }
touch(tmpfile("foo.rb"))
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -180,11 +190,13 @@ module FileUpdateCheckerSharedTests
checker = new_checker([], tmpdir => [:rb, :txt]) { i += 1 }
touch(tmpfile("foo.rb"))
+ wait
assert checker.execute_if_updated
assert_equal 1, i
touch(tmpfile("foo.txt"))
+ wait
assert checker.execute_if_updated
assert_equal 2, i
@@ -196,6 +208,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker([], tmpdir => :txt) { i += 1 }
touch(tmpfile("foo.rb"))
+ wait
assert !checker.execute_if_updated
assert_equal 0, i
@@ -208,6 +221,7 @@ module FileUpdateCheckerSharedTests
checker = new_checker([non_existing]) { i += 1 }
touch(non_existing)
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -226,6 +240,7 @@ module FileUpdateCheckerSharedTests
assert_equal 0, i
touch(File.join(subdir, "nested.rb"))
+ wait
assert checker.execute_if_updated
assert_equal 1, i
@@ -240,17 +255,20 @@ module FileUpdateCheckerSharedTests
checker = new_checker([], tmpdir => :rb, subdir => :txt) { i += 1 }
touch(tmpfile("new.txt"))
+ wait
assert !checker.execute_if_updated
assert_equal 0, i
# subdir does not look for Ruby files, but its parent tmpdir does.
touch(File.join(subdir, "nested.rb"))
+ wait
assert checker.execute_if_updated
assert_equal 1, i
touch(File.join(subdir, "nested.txt"))
+ wait
assert checker.execute_if_updated
assert_equal 2, i
diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md
index a45becf670..d91c9bd606 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -467,6 +467,8 @@ the first time (i.e. on the date the migration is applied).
Some adapters may support additional options; see the adapter specific API docs
for further information.
+NOTE: `null` and `default` cannot be specified via command line.
+
### Foreign Keys
While it's not required you might want to add foreign key constraints to
@@ -1018,10 +1020,10 @@ such features, the `execute` method can be used to execute arbitrary SQL.
Migrations and Seed Data
------------------------
-The main purpose of Rails' migration feature is to issue commands that modify the
-schema using a consistent process. Migrations can also be used
-to add or modify data. This is useful in an existing database that can't be destroyed
-and recreated, such as a production database.
+The main purpose of Rails' migration feature is to issue commands that modify the
+schema using a consistent process. Migrations can also be used
+to add or modify data. This is useful in an existing database that can't be destroyed
+and recreated, such as a production database.
```ruby
class AddInitialProducts < ActiveRecord::Migration[5.0]
@@ -1037,10 +1039,10 @@ class AddInitialProducts < ActiveRecord::Migration[5.0]
end
```
-To add initial data after a database is created, Rails has a built-in
-'seeds' feature that makes the process quick and easy. This is especially
-useful when reloading the database frequently in development and test environments.
-It's easy to get started with this feature: just fill up `db/seeds.rb` with some
+To add initial data after a database is created, Rails has a built-in
+'seeds' feature that makes the process quick and easy. This is especially
+useful when reloading the database frequently in development and test environments.
+It's easy to get started with this feature: just fill up `db/seeds.rb` with some
Ruby code, and run `rails db:seed`:
```ruby
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 60a6c37f82..70b04a9695 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -2661,7 +2661,7 @@ The method `transform_keys` accepts a block and returns a hash that has applied
```ruby
{nil => nil, 1 => 1, a: :a}.transform_keys { |key| key.to_s.upcase }
-# => {"" => nil, "A" => :a, "1" => 1}
+# => {"" => nil, "1" => 1, "A" => :a}
```
In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
@@ -2703,7 +2703,7 @@ The method `stringify_keys` returns a hash that has a stringified version of the
```ruby
{nil => nil, 1 => 1, a: :a}.stringify_keys
-# => {"" => nil, "a" => :a, "1" => 1}
+# => {"" => nil, "1" => 1, "a" => :a}
```
In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
@@ -2745,7 +2745,7 @@ The method `symbolize_keys` returns a hash that has a symbolized version of the
```ruby
{nil => nil, 1 => 1, "a" => "a"}.symbolize_keys
-# => {1=>1, nil=>nil, :a=>"a"}
+# => {nil=>nil, 1=>1, :a=>"a"}
```
WARNING. Note in the previous example only one key was symbolized.
@@ -2822,7 +2822,7 @@ Ruby has built-in support for taking slices out of strings and arrays. Active Su
```ruby
{a: 1, b: 2, c: 3}.slice(:a, :c)
-# => {:c=>3, :a=>1}
+# => {:a=>1, :c=>3}
{a: 1, b: 2, c: 3}.slice(:b, :X)
# => {:b=>2} # non-existing keys are ignored