aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb2
-rw-r--r--activerecord/test/cases/persistence_test.rb9
4 files changed, 18 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 771f1333f0..4a6e79c68e 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,4 +1,11 @@
## Rails 4.0.0 (unreleased) ##
+* After extraction of mass-assignment attributes (which protects [id, type]
+ by default) we can pass id to update_attributes and it will update
+ another record because id will be used in where statement. We never have
+ to change id in where statement because we try to set/replace fields for
+ already loaded record but we have to try to set new id for that record.
+
+ *Dmitry Vorotilin*
* Models with multiple counter cache associations now update correctly on destroy.
See #7706.
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index aa92343f76..769e005c8f 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -348,7 +348,7 @@ module ActiveRecord
# Filters the primary keys and readonly attributes from the attribute names.
def attributes_for_update(attribute_names)
attribute_names.select do |name|
- column_for_attribute(name) && !pk_attribute?(name) && !readonly_attribute?(name)
+ column_for_attribute(name) && !readonly_attribute?(name)
end
end
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index b25d0601cb..f881778591 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -443,7 +443,7 @@ module ActiveRecord
real_column = db_columns_with_values[i].first
bind_attrs[column] = klass.connection.substitute_at(real_column, i)
end
- stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(bind_attrs)
+ stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id_was)).arel.compile_update(bind_attrs)
klass.connection.update stmt, 'SQL', db_columns_with_values
end
end
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index b936cca875..a29189df05 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -661,6 +661,15 @@ class PersistencesTest < ActiveRecord::TestCase
topic.reload
assert !topic.approved?
assert_equal "The First Topic", topic.title
+
+ assert_raise(ActiveRecord::RecordNotUnique, ActiveRecord::StatementInvalid) do
+ topic.update_attributes(id: 3, title: "Hm is it possible?")
+ end
+ assert_not_equal "Hm is it possible?", Topic.find(3).title
+
+ topic.update_attributes(id: 1234)
+ assert_nothing_raised { topic.reload }
+ assert_equal topic.title, Topic.find(1234).title
end
def test_update!