From 5b61168aafb28b9d4dcbe7651d6a5a63cdb68b32 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Thu, 30 Apr 2009 13:21:13 -0300 Subject: Added arel_attributes_values methods, refactored locking and AR#update to use this method --- activerecord/lib/active_record/base.rb | 32 ++++++++++++++++------ .../lib/active_record/locking/optimistic.rb | 9 +----- arel | 2 +- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8882a00dd5..5807d62f2a 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1077,7 +1077,7 @@ module ActiveRecord #:nodoc: # Returns an array of all the attributes that have been specified as readonly. def readonly_attributes - read_inheritable_attribute(:attr_readonly) + read_inheritable_attribute(:attr_readonly) || [] end # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, @@ -2946,14 +2946,9 @@ module ActiveRecord #:nodoc: # Updates the associated record with values matching those of the instance attributes. # Returns the number of affected rows. def update(attribute_names = @attributes.keys) - quoted_attributes = attributes_with_quotes(false, false, attribute_names) - return 0 if quoted_attributes.empty? - connection.update( - "UPDATE #{self.class.quoted_table_name} " + - "SET #{quoted_comma_pair_list(connection, quoted_attributes)} " + - "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}", - "#{self.class.name} Update" - ) + attributes_with_values = arel_attributes_values(false, false, attribute_names) + return 0 if attributes_with_values.empty? + table.where(table[self.class.primary_key].eq(id)).update(attributes_with_values) end # Creates a record with values matching those of the instance attributes @@ -3063,6 +3058,25 @@ module ActiveRecord #:nodoc: include_readonly_attributes ? quoted : remove_readonly_attributes(quoted) end + def table + @arel_table ||= Arel(self.class.table_name) + end + + def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys) + attrs = {} + connection = self.class.connection + attribute_names.each do |name| + if (column = column_for_attribute(name)) && (include_primary_key || !column.primary) + value = read_attribute(name) + + if include_readonly_attributes || (!include_readonly_attributes && !self.class.readonly_attributes.include?(name)) + attrs[table[name]] = value + end + end + end + attrs + end + # Quote strings appropriately for SQL statements. def quote_value(value, column = nil) self.class.connection.quote(value, column) diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 1251e9f013..bb28444b07 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -89,18 +89,11 @@ module ActiveRecord attribute_names.uniq! begin - table = Arel(self.class.table_name) - - attributes = {} - attributes_with_quotes(false, false, attribute_names).map { |k,v| - attributes.merge!(table[k] => v) - } - affected_rows = table.where( table[self.class.primary_key].eq(quoted_id).and( table[self.class.locking_column].eq(quote_value(previous_value)) ) - ).update(attributes) + ).update(arel_attributes_values(false, false, attribute_names)) unless affected_rows == 1 diff --git a/arel b/arel index b4b73d9520..092c2be685 160000 --- a/arel +++ b/arel @@ -1 +1 @@ -Subproject commit b4b73d9520a2ff27021b530ccd3dcd96973ce5fe +Subproject commit 092c2be685e8e359c161144ce58addac6caa5c44 -- cgit v1.2.3