aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb4
-rw-r--r--activerecord/lib/active_record/attribute_set.rb5
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb11
-rw-r--r--activerecord/test/cases/attribute_set_test.rb8
-rw-r--r--activesupport/test/json/decoding_test.rb30
-rw-r--r--activesupport/test/json/encoding_test.rb33
-rw-r--r--guides/source/active_record_migrations.md3
7 files changed, 66 insertions, 28 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 268cec6160..267377cec6 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -271,9 +271,7 @@ module ActiveRecord
# person.attributes
# # => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
def attributes
- attribute_names.each_with_object({}) { |name, attrs|
- attrs[name] = read_attribute(name)
- }
+ @attributes.to_hash
end
# Returns an <tt>#inspect</tt>-like string for the value of the
diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb
index 098e43cd57..8f6b73eac2 100644
--- a/activerecord/lib/active_record/attribute_set.rb
+++ b/activerecord/lib/active_record/attribute_set.rb
@@ -10,6 +10,11 @@ module ActiveRecord
attributes.update(other.attributes)
end
+ def to_hash
+ attributes.each_with_object({}) { |(k, v), h| h[k] = v.value }
+ end
+ alias_method :to_h, :to_hash
+
def freeze
@attributes.freeze
super
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index f832ca3451..84a7a8ef68 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -831,6 +831,17 @@ class AttributeMethodsTest < ActiveRecord::TestCase
end
end
+ def test_attribute_method?
+ assert @target.attribute_method?(:title)
+ assert @target.attribute_method?(:title=)
+ assert_not @target.attribute_method?(:wibble)
+ end
+
+ def test_attribute_method_returns_false_if_table_does_not_exist
+ @target.table_name = 'wibble'
+ assert_not @target.attribute_method?(:title)
+ end
+
private
def new_topic_like_ar_class(&block)
diff --git a/activerecord/test/cases/attribute_set_test.rb b/activerecord/test/cases/attribute_set_test.rb
index e3f0304de2..402a611efa 100644
--- a/activerecord/test/cases/attribute_set_test.rb
+++ b/activerecord/test/cases/attribute_set_test.rb
@@ -53,5 +53,13 @@ module ActiveRecord
assert clone.frozen?
assert_not attributes.frozen?
end
+
+ test "to_hash returns a hash of the type cast values" do
+ builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new)
+ attributes = builder.build_from_database(foo: '1.1', bar: '2.2')
+
+ assert_equal({ foo: 1, bar: 2.2 }, attributes.to_hash)
+ assert_equal({ foo: 1, bar: 2.2 }, attributes.to_h)
+ end
end
end
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index 07d7e530ca..80bf255080 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -73,22 +73,20 @@ class TestJSONDecoding < ActiveSupport::TestCase
TESTS.each_with_index do |(json, expected), index|
test "json decodes #{index}" do
- prev = ActiveSupport.parse_json_times
- ActiveSupport.parse_json_times = true
- silence_warnings do
- assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
- failed for #{json}"
+ with_parse_json_times(true) do
+ silence_warnings do
+ assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
+ failed for #{json}"
+ end
end
- ActiveSupport.parse_json_times = prev
end
end
test "json decodes time json with time parsing disabled" do
- prev = ActiveSupport.parse_json_times
- ActiveSupport.parse_json_times = false
- expected = {"a" => "2007-01-01 01:12:34 Z"}
- assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
- ActiveSupport.parse_json_times = prev
+ with_parse_json_times(false) do
+ expected = {"a" => "2007-01-01 01:12:34 Z"}
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
+ end
end
def test_failed_json_decoding
@@ -101,5 +99,15 @@ class TestJSONDecoding < ActiveSupport::TestCase
def test_cannot_pass_unsupported_options
assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) }
end
+
+ private
+
+ def with_parse_json_times(value)
+ old_value = ActiveSupport.parse_json_times
+ ActiveSupport.parse_json_times = value
+ yield
+ ensure
+ ActiveSupport.parse_json_times = old_value
+ end
end
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index b4cf37b177..ad358ad21d 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -494,31 +494,28 @@ EXPECTED
def test_twz_to_json_with_custom_time_precision
with_standard_json_time_format(true) do
- ActiveSupport::JSON::Encoding.time_precision = 0
- zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
- time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
- assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(time)
+ with_time_precision(0) do
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
+ assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(time)
+ end
end
- ensure
- ActiveSupport::JSON::Encoding.time_precision = 3
end
def test_time_to_json_with_custom_time_precision
with_standard_json_time_format(true) do
- ActiveSupport::JSON::Encoding.time_precision = 0
- assert_equal "\"2000-01-01T00:00:00Z\"", ActiveSupport::JSON.encode(Time.utc(2000))
+ with_time_precision(0) do
+ assert_equal "\"2000-01-01T00:00:00Z\"", ActiveSupport::JSON.encode(Time.utc(2000))
+ end
end
- ensure
- ActiveSupport::JSON::Encoding.time_precision = 3
end
def test_datetime_to_json_with_custom_time_precision
with_standard_json_time_format(true) do
- ActiveSupport::JSON::Encoding.time_precision = 0
- assert_equal "\"2000-01-01T00:00:00+00:00\"", ActiveSupport::JSON.encode(DateTime.new(2000))
+ with_time_precision(0) do
+ assert_equal "\"2000-01-01T00:00:00+00:00\"", ActiveSupport::JSON.encode(DateTime.new(2000))
+ end
end
- ensure
- ActiveSupport::JSON::Encoding.time_precision = 3
end
def test_twz_to_json_when_wrapping_a_date_time
@@ -539,4 +536,12 @@ EXPECTED
ensure
ActiveSupport.use_standard_json_time_format = old
end
+
+ def with_time_precision(value)
+ old_value = ActiveSupport::JSON::Encoding.time_precision
+ ActiveSupport::JSON::Encoding.time_precision = value
+ yield
+ ensure
+ ActiveSupport::JSON::Encoding.time_precision = old_value
+ end
end
diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md
index 5a550d9e55..fd2125424b 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -434,6 +434,9 @@ change_column_default :products, :approved, false
This sets `:name` field on products to a `NOT NULL` column and the default
value of the `:approved` field to false.
+TIP: Unlike `change_column` (and `change_column_default`), `change_column_null`
+is reversible.
+
### Column Modifiers
Column modifiers can be applied when creating or changing a column: