diff options
author | Aaron Pfeifer <aaron.pfeifer@gmail.com> | 2013-02-26 09:35:03 -0500 |
---|---|---|
committer | Aaron Pfeifer <aaron.pfeifer@gmail.com> | 2013-03-18 22:09:01 -0400 |
commit | a240e526a8b4c5948a1c2a8ec49b6e2d1ad6ad23 (patch) | |
tree | f6639671decafa03597722f77238607b1f31bfbc /activerecord/lib/active_record | |
parent | 111611b511c27ec29be6a8837de6d8f25cded5a7 (diff) | |
download | rails-a240e526a8b4c5948a1c2a8ec49b6e2d1ad6ad23.tar.gz rails-a240e526a8b4c5948a1c2a8ec49b6e2d1ad6ad23.tar.bz2 rails-a240e526a8b4c5948a1c2a8ec49b6e2d1ad6ad23.zip |
Fix ActiveRecord locking column defaults not getting persisted
When partial inserts are enabled, overridden db defaults are ignored. This
results in locking columns having a nil value for new records if the db default
is null. This happens because the list of changed attributes for new records is
always assumed to be empty.
Solution: When a new record's default attributes are set, also initialize the
list of changed attributes by comparing current values against what's stored as
the column defaults in the database.
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/core.rb | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index aa56219755..1908448f90 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -176,6 +176,7 @@ module ActiveRecord @columns_hash = self.class.column_types.dup init_internals + init_changed_attributes ensure_proper_type populate_with_current_scope_attributes @@ -246,9 +247,7 @@ module ActiveRecord run_callbacks(:initialize) unless _initialize_callbacks.empty? @changed_attributes = {} - self.class.column_defaults.each do |attr, orig_value| - @changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr]) - end + init_changed_attributes @aggregation_cache = {} @association_cache = {} @@ -433,5 +432,14 @@ module ActiveRecord @transaction_state = nil @reflects_state = [false] end + + def init_changed_attributes + # Intentionally avoid using #column_defaults since overriden defaults (as is done in + # optimistic locking) won't get written unless they get marked as changed + self.class.columns.each do |c| + attr, orig_value = c.name, c.default + @changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr]) + end + end end end |