Patch:
module ActiveRecord
class Base
def update_attribute(name, value)
update_attributes(name => value)
end
def update_attributes(new_attributes)
return if new_attributes.nil?
attributes = new_attributes.dup
attributes.stringify_keys!
self.attributes = attributes
update(attributes)
end
private
def update(attrs = nil)
connection.update(
"UPDATE #{self.class.table_name} " +
"SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, attrs))} " +
"WHERE #{self.class.primary_key} = #{quote(id)}",
"#{self.class.name} Update"
)
return true
end
def attributes_with_quotes(include_primary_key = true, attrs = nil)
(attrs || attributes).inject({}) do |quoted, (name, value)|
if column = column_for_attribute(name)
quoted[name] = quote(value, column) unless !include_primary_key && column.primary
end
quoted
end
end
end
end
module ActiveRecord
module ValidationsFix
def self.append_features(base) # :nodoc:
super
base.class_eval do
alias_method :update_attributes_without_validation, :update_attributes
alias_method :update_attributes, :update_attributes_with_validation
end
end
def update_attributes_with_validation(new_attributes)
return if new_attributes.nil?
attributes = new_attributes.dup
attributes.stringify_keys!
self.attributes = attributes
if valid?
update_attributes_without_validation(attributes)
else
return false
end
end
end
end
ActiveRecord::Base.class_eval do
include ActiveRecord::ValidationsFix
end
Test schema:
create table posts(
id serial not null primary key,
title varchar(255),
body text,
status integer not null default 0
);
insert into posts(title, body) values('Hello, World!', 'Long Text...');
Test code:
Post.find(:first).update_attribute(:status, 1)
Without this patch, it generate query string:
UPDATE posts SET "title" = 'Hello, World!', "status" = 1, "body" = 'Long Text...' WHERE id = 1
With this patch:
UPDATE posts SET "status" = 2 WHERE id = 1
Update two attributes:
Post.find(:first).update_attributes(:title => 'Aha', :status => 2)
Query string:
UPDATE posts SET "title" = 'Aha', "status" = 2 WHERE id = 1