diff options
-rw-r--r-- | activerecord/lib/active_record/attribute/user_provided_default.rb | 15 | ||||
-rw-r--r-- | activerecord/lib/active_record/attributes.rb | 1 | ||||
-rw-r--r-- | activerecord/test/cases/attributes_test.rb | 6 | ||||
-rw-r--r-- | activerecord/test/cases/dirty_test.rb | 26 |
4 files changed, 21 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/attribute/user_provided_default.rb b/activerecord/lib/active_record/attribute/user_provided_default.rb index 29d37ac689..e0bee8c17e 100644 --- a/activerecord/lib/active_record/attribute/user_provided_default.rb +++ b/activerecord/lib/active_record/attribute/user_provided_default.rb @@ -3,8 +3,9 @@ require 'active_record/attribute' module ActiveRecord class Attribute # :nodoc: class UserProvidedDefault < FromUser - def initialize(name, value, type) + def initialize(name, value, type, database_default) super(name, value, type) + @database_default = database_default end def type_cast(value) @@ -14,6 +15,18 @@ module ActiveRecord super end end + + def changed_in_place_from?(old_value) + super || changed_from?(database_default.value) + end + + def with_type(type) + self.class.new(name, value_before_type_cast, type, database_default) + end + + protected + + attr_reader :database_default end end end diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb index e574aebd6c..c89099589e 100644 --- a/activerecord/lib/active_record/attributes.rb +++ b/activerecord/lib/active_record/attributes.rb @@ -242,6 +242,7 @@ module ActiveRecord name, value, type, + _default_attributes[name], ) else default_attribute = Attribute.from_database(name, value, type) diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb index 4619293ac6..eeda9335ad 100644 --- a/activerecord/test/cases/attributes_test.rb +++ b/activerecord/test/cases/attributes_test.rb @@ -135,6 +135,12 @@ module ActiveRecord assert_equal 2, klass.new.counter end + test "user provided defaults are persisted even if unchanged" do + model = OverloadedType.create! + + assert_equal "the overloaded default", model.reload.string_with_default + end + if current_adapter?(:PostgreSQLAdapter) test "arrays types can be specified" do klass = Class.new(OverloadedType) do diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index 3a7cc572e6..216f228142 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -623,32 +623,6 @@ class DirtyTest < ActiveRecord::TestCase end end - test "defaults with type that implements `serialize`" do - type = Class.new(ActiveRecord::Type::Value) do - def cast(value) - value.to_i - end - - def serialize(value) - value.to_s - end - end - - model_class = Class.new(ActiveRecord::Base) do - self.table_name = 'numeric_data' - attribute :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 - test "in place mutation detection" do pirate = Pirate.create!(catchphrase: "arrrr") pirate.catchphrase << " matey!" |