diff options
author | Sean Griffin <sean@thoughtbot.com> | 2015-05-28 16:33:38 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2015-05-28 16:40:26 -0600 |
commit | 2f9d88954caf4fd75098e813a3ab8bf50ef6ace4 (patch) | |
tree | 6a105c43031fc521144021284553905344e4bc79 /activerecord/lib | |
parent | a6e3cdae0ce1d05a6b9f7dff4499f6be3fbf63c2 (diff) | |
download | rails-2f9d88954caf4fd75098e813a3ab8bf50ef6ace4.tar.gz rails-2f9d88954caf4fd75098e813a3ab8bf50ef6ace4.tar.bz2 rails-2f9d88954caf4fd75098e813a3ab8bf50ef6ace4.zip |
Persist user provided default values, even if unchanged
This is a usability change to fix a quirk from our definition of partial
writes. By default, we only persist changed attributes. When creating a
new record, this is assumed that the default values came from the
database. However, if the user provided a default, it will not be
persisted, since we didn't see it as "changed". Since this is a very
specific case, I wanted to isolate it with the other quirks that come
from user provided default values. The number of edge cases which are
presenting themselves are starting to make me wonder if we should just
remove the ability to assign a default, in favor of overriding
`initialize`. For the time being, this is required for the attributes
API to not have confusing behavior.
We had to delete one test, since this actually changes the meaning of
`.changed?` on Active Record models. It now specifically means
`changed_from_database?`. While I think this will make the attributes
API more ergonomic to use, it is a subtle change in definition (though
not a backwards incompatible one). We should probably figure out the
right place to document this. (Feel free to open a PR doing that if
you're reading this).
/cc @rafaelfranca @kirs @senny
This is an alternate implementation of #19921.
Close #19921.
[Sean Griffin & Kir Shatrov]
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/attribute/user_provided_default.rb | 15 | ||||
-rw-r--r-- | activerecord/lib/active_record/attributes.rb | 1 |
2 files changed, 15 insertions, 1 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) |