diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-03 18:49:50 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-03 18:49:50 -0300 |
commit | a58dfea3e83a88de34e1499dfbc10435abe385de (patch) | |
tree | fcbe0d792e7c07aba862498147b9720bb62a1b5f | |
parent | fcd4d8a07db07f85d5a008f2c822d4ba2728a65f (diff) | |
parent | ed559d4b00fbd7c6f86e75fd2d18a40e16b98281 (diff) | |
download | rails-a58dfea3e83a88de34e1499dfbc10435abe385de.tar.gz rails-a58dfea3e83a88de34e1499dfbc10435abe385de.tar.bz2 rails-a58dfea3e83a88de34e1499dfbc10435abe385de.zip |
Merge pull request #15492 from sgrif/sg-dirty-defaults
Keep column defaults in type cast form
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/column.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/core.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/model_schema.rb | 9 | ||||
-rw-r--r-- | activerecord/lib/active_record/properties.rb | 1 | ||||
-rw-r--r-- | activerecord/test/cases/dirty_test.rb | 28 |
5 files changed, 40 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index 34054589d0..3b0dcbc6a7 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -52,7 +52,7 @@ module ActiveRecord end def extract_default(default) - type_cast_for_write(type_cast(default)) + type_cast(default) end end end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 1d75eeda69..4a6f062220 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -249,7 +249,7 @@ module ActiveRecord # # Instantiates a single new object # User.new(first_name: 'Jamie') def initialize(attributes = nil, options = {}) - defaults = self.class.column_defaults.dup + defaults = self.class.raw_column_defaults.dup defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? } @raw_attributes = defaults diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb index f0ddf202c3..baf2b5fbf8 100644 --- a/activerecord/lib/active_record/model_schema.rb +++ b/activerecord/lib/active_record/model_schema.rb @@ -241,6 +241,14 @@ module ActiveRecord @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }] end + # Returns a hash where the keys are the column names and the values + # are the default values suitable for use in `@raw_attriubtes` + def raw_column_defaults # :nodoc: + @raw_column_defauts ||= Hash[column_defaults.map { |name, default| + [name, columns_hash[name].type_cast_for_write(default)] + }] + end + # Returns an array of column names as strings. def column_names @column_names ||= columns.map { |column| column.name } @@ -285,6 +293,7 @@ module ActiveRecord @arel_engine = nil @column_defaults = nil + @raw_column_defauts = nil @column_names = nil @column_types = nil @content_columns = nil diff --git a/activerecord/lib/active_record/properties.rb b/activerecord/lib/active_record/properties.rb index 5fd51e09fa..48ee42aaca 100644 --- a/activerecord/lib/active_record/properties.rb +++ b/activerecord/lib/active_record/properties.rb @@ -113,6 +113,7 @@ module ActiveRecord @columns_hash = nil @column_types = nil @column_defaults = nil + @raw_column_defaults = nil @column_names = nil @content_columns = nil end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index df4183c065..987c55ebc2 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -616,6 +616,34 @@ class DirtyTest < ActiveRecord::TestCase end end + test "defaults with type that implements `type_cast_for_write`" do + type = Class.new(ActiveRecord::Type::Value) do + def type_cast(value) + value.to_i + end + + def type_cast_for_write(value) + value.to_s + end + + alias type_cast_for_database type_cast_for_write + end + + model_class = Class.new(ActiveRecord::Base) do + self.table_name = 'numeric_data' + property :foo, type.new, default: 1 + end + + model = model_class.new + assert_not model.foo_changed? + + model = model_class.new(foo: 1) + assert_not model.foo_changed? + + model = model_class.new(foo: '1') + assert_not model.foo_changed? + end + private def with_partial_writes(klass, on = true) old = klass.partial_writes? |