提交 0e67f793 编写于 作者: C Carlos Antonio da Silva

Unscope update_column(s) query to ignore default scope

When applying default_scope to a class with a where clause, using
update_column(s) could generate a query that would not properly update
the record due to the where clause from the default_scope being applied
to the update query.

    class User < ActiveRecord::Base
      default_scope where(active: true)
    end

    user = User.first
    user.active = false
    user.save!

    user.update_column(:active, true) # => false

In this situation we want to skip the default_scope clause and just
update the record based on the primary key. With this change:

    user.update_column(:active, true) # => true

Fixes #8436.
上级 1eaf3db8
## Rails 4.0.0 (unreleased) ##
* Unscope `update_column(s)` query to ignore default scope.
When applying `default_scope` to a class with a where clause, using
`update_column(s)` could generate a query that would not properly update
the record due to the where clause from the `default_scope` being applied
to the update query.
class User < ActiveRecord::Base
default_scope where(active: true)
end
user = User.first
user.active = false
user.save!
user.update_column(:active, true) # => false
In this situation we want to skip the default_scope clause and just
update the record based on the primary key. With this change:
user.update_column(:active, true) # => true
Fixes #8436.
*Carlos Antonio da Silva*
* SQLite adapter no longer corrupts binary data if the data contains `%00`.
*Chris Feist*
......
......@@ -259,7 +259,7 @@ def update_columns(attributes)
verify_readonly_attribute(key.to_s)
end
updated_count = self.class.where(self.class.primary_key => id).update_all(attributes)
updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)
attributes.each do |k, v|
raw_write_attribute(k, v)
......
......@@ -512,6 +512,14 @@ def test_update_column_with_one_changed_and_one_updated
assert_equal 'super_title', t.title
end
def test_update_column_with_default_scope
developer = DeveloperCalledDavid.first
developer.name = 'John'
developer.save!
assert developer.update_column(:name, 'Will'), 'did not update record due to default scope'
end
def test_update_columns
topic = Topic.find(1)
topic.update_columns({ "approved" => true, title: "Sebastian Topic" })
......@@ -616,6 +624,14 @@ def test_update_columns_returns_boolean
assert_equal true, topic.update_columns(title: "New title")
end
def test_update_columns_with_default_scope
developer = DeveloperCalledDavid.first
developer.name = 'John'
developer.save!
assert developer.update_columns(name: 'Will'), 'did not update record due to default scope'
end
def test_update_attributes
topic = Topic.find(1)
assert !topic.approved?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册