diff options
-rw-r--r-- | activerecord/lib/active_record/attribute_methods.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_set.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/attribute_methods_test.rb | 11 | ||||
-rw-r--r-- | activerecord/test/cases/attribute_set_test.rb | 8 | ||||
-rw-r--r-- | activesupport/test/json/decoding_test.rb | 30 | ||||
-rw-r--r-- | activesupport/test/json/encoding_test.rb | 33 | ||||
-rw-r--r-- | guides/source/active_record_migrations.md | 3 |
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: |