aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/attribute/user_provided_default.rb15
-rw-r--r--activerecord/lib/active_record/attributes.rb1
-rw-r--r--activerecord/test/cases/attributes_test.rb6
-rw-r--r--activerecord/test/cases/dirty_test.rb26
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!"