From eb6cee9cf7fd7c22fe3190e2660eeefdd5ec651f Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Fri, 30 May 2014 09:05:18 -0700
Subject: Rename attribute related instance variables to better express intent

`@attributes` was actually used for `_before_type_cast` and friends,
while `@attributes_cache` is the type cast version (and caching is the
wrong word there, but I'm working on removing the conditionals around
that). I opted for `@raw_attributes`, because `_before_type_cast` is
also semantically misleading. The values in said hash are in the state
given by the form builder or database, so raw seemed to be a good word.
---
 .../lib/active_record/attribute_methods.rb         | 10 +++++-----
 .../attribute_methods/before_type_cast.rb          |  4 ++--
 .../lib/active_record/attribute_methods/dirty.rb   |  2 +-
 .../lib/active_record/attribute_methods/read.rb    | 10 +++++-----
 .../attribute_methods/serialization.rb             |  4 ++--
 .../attribute_methods/time_zone_conversion.rb      |  2 +-
 .../lib/active_record/attribute_methods/write.rb   | 10 +++++-----
 activerecord/lib/active_record/core.rb             | 22 +++++++++++-----------
 .../lib/active_record/locking/optimistic.rb        |  2 +-
 activerecord/lib/active_record/persistence.rb      | 10 +++++-----
 activerecord/lib/active_record/result.rb           |  2 +-
 activerecord/lib/active_record/transactions.rb     |  8 ++++----
 activerecord/test/cases/attribute_methods_test.rb  |  2 +-
 13 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index a0a0214eae..fb6473b7c7 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -239,9 +239,9 @@ module ActiveRecord
 
       # If the result is true then check for the select case.
       # For queries selecting a subset of columns, return false for unselected columns.
-      # We check defined?(@attributes) not to issue warnings if called on objects that
+      # We check defined?(@raw_attributes) not to issue warnings if called on objects that
       # have been allocated but not yet initialized.
-      if defined?(@attributes) && @attributes.any? && self.class.column_names.include?(name)
+      if defined?(@raw_attributes) && @raw_attributes.any? && self.class.column_names.include?(name)
         return has_attribute?(name)
       end
 
@@ -258,7 +258,7 @@ module ActiveRecord
     #   person.has_attribute?('age')    # => true
     #   person.has_attribute?(:nothing) # => false
     def has_attribute?(attr_name)
-      @attributes.has_key?(attr_name.to_s)
+      @raw_attributes.has_key?(attr_name.to_s)
     end
 
     # Returns an array of names for the attributes available on this object.
@@ -270,7 +270,7 @@ module ActiveRecord
     #   person.attribute_names
     #   # => ["id", "created_at", "updated_at", "name", "age"]
     def attribute_names
-      @attributes.keys
+      @raw_attributes.keys
     end
 
     # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
@@ -424,7 +424,7 @@ module ActiveRecord
 
     def attribute_method?(attr_name) # :nodoc:
       # We check defined? because Syck calls respond_to? before actually calling initialize.
-      defined?(@attributes) && @attributes.include?(attr_name)
+      defined?(@raw_attributes) && @raw_attributes.include?(attr_name)
     end
 
     private
diff --git a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
index f596a8b02e..4365f5a1a1 100644
--- a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
+++ b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
@@ -43,7 +43,7 @@ module ActiveRecord
       #   task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
       #   task.read_attribute_before_type_cast(:completed_on)  # => "2012-10-21"
       def read_attribute_before_type_cast(attr_name)
-        @attributes[attr_name.to_s]
+        @raw_attributes[attr_name.to_s]
       end
 
       # Returns a hash of attributes before typecasting and deserialization.
@@ -57,7 +57,7 @@ module ActiveRecord
       #   task.attributes_before_type_cast
       #   # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
       def attributes_before_type_cast
-        @attributes
+        @raw_attributes
       end
 
       private
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 99070f127b..ad01b5bf25 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -55,7 +55,7 @@ module ActiveRecord
         # 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])
+          changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @raw_attributes[attr])
         end
       end
 
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 979dfb207e..99b95b1fc4 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -22,7 +22,7 @@ module ActiveRecord
         # the attribute name. Using a constant means that we do not have
         # to allocate an object on each call to the attribute method.
         # Making it frozen means that it doesn't get duped when used to
-        # key the @attributes_cache in read_attribute.
+        # key the @attributes in read_attribute.
         def method_body(method_name, const_name)
           <<-EOMETHOD
           def #{method_name}
@@ -108,22 +108,22 @@ module ActiveRecord
         # If it's cached, just return it
         # We use #[] first as a perf optimization for non-nil values. See https://gist.github.com/jonleighton/3552829.
         name = attr_name.to_s
-        @attributes_cache[name] || @attributes_cache.fetch(name) {
+        @attributes[name] || @attributes.fetch(name) {
           column = @column_types_override[name] if @column_types_override
           column ||= @column_types[name]
 
-          return @attributes.fetch(name) {
+          return @raw_attributes.fetch(name) {
             if name == 'id' && self.class.primary_key != name
               read_attribute(self.class.primary_key)
             end
           } unless column
 
-          value = @attributes.fetch(name) {
+          value = @raw_attributes.fetch(name) {
             return block_given? ? yield(name) : nil
           }
 
           if self.class.cache_attribute?(name)
-            @attributes_cache[name] = column.type_cast(value)
+            @attributes[name] = column.type_cast(value)
           else
             column.type_cast value
           end
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 65d910fd46..b247bf8a45 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -127,7 +127,7 @@ module ActiveRecord
 
         def typecasted_attribute_value(name)
           if self.class.serialized_attributes.include?(name)
-            @attributes[name].serialized_value
+            @raw_attributes[name].serialized_value
           else
             super
           end
@@ -136,7 +136,7 @@ module ActiveRecord
         def attributes_for_coder
           attribute_names.each_with_object({}) do |name, attrs|
             attrs[name] = if self.class.serialized_attributes.include?(name)
-                            @attributes[name].serialized_value
+                            @raw_attributes[name].serialized_value
                           else
                             read_attribute(name)
                           end
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index 6149ac4906..18778698e8 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -36,7 +36,7 @@ module ActiveRecord
                 previous_time = attribute_changed?("#{attr_name}") ? changed_attributes["#{attr_name}"] : read_attribute(:#{attr_name})
                 write_attribute(:#{attr_name}, time)
                 #{attr_name}_will_change! if previous_time != time_with_zone
-                @attributes_cache["#{attr_name}"] = time_with_zone
+                @attributes["#{attr_name}"] = time_with_zone
               end
             EOV
             generated_attribute_methods.module_eval(method_body, __FILE__, line)
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index 629bd3bc63..3b9b9c81e8 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -69,19 +69,19 @@ module ActiveRecord
       def write_attribute_with_type_cast(attr_name, value, type_cast_method)
         attr_name = attr_name.to_s
         attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
-        @attributes_cache.delete(attr_name)
+        @attributes.delete(attr_name)
         column = column_for_attribute(attr_name)
 
         # If we're dealing with a binary column, write the data to the cache
         # so we don't attempt to typecast multiple times.
         if column && column.binary?
-          @attributes_cache[attr_name] = value
+          @attributes[attr_name] = value
         end
 
         if column
-          @attributes[attr_name] = column.public_send(type_cast_method, value)
-        elsif @attributes.has_key?(attr_name)
-          @attributes[attr_name] = value
+          @raw_attributes[attr_name] = column.public_send(type_cast_method, value)
+        elsif @raw_attributes.has_key?(attr_name)
+          @raw_attributes[attr_name] = value
         else
           raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'"
         end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 07eafef788..e99e235fe8 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -252,7 +252,7 @@ module ActiveRecord
       defaults = self.class.column_defaults.dup
       defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? }
 
-      @attributes   = self.class.initialize_attributes(defaults)
+      @raw_attributes = self.class.initialize_attributes(defaults)
       @column_types_override = nil
       @column_types = self.class.column_types
 
@@ -278,7 +278,7 @@ module ActiveRecord
     #   post.init_with('attributes' => { 'title' => 'hello world' })
     #   post.title # => 'hello world'
     def init_with(coder)
-      @attributes   = self.class.initialize_attributes(coder['attributes'])
+      @raw_attributes = self.class.initialize_attributes(coder['attributes'])
       @column_types_override = coder['column_types']
       @column_types = self.class.column_types
 
@@ -325,14 +325,14 @@ module ActiveRecord
       cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
       self.class.initialize_attributes(cloned_attributes, :serialized => false)
 
-      @attributes = cloned_attributes
-      @attributes[self.class.primary_key] = nil
+      @raw_attributes = cloned_attributes
+      @raw_attributes[self.class.primary_key] = nil
 
       run_callbacks(:initialize) unless _initialize_callbacks.empty?
 
       @aggregation_cache = {}
       @association_cache = {}
-      @attributes_cache  = {}
+      @attributes        = {}
 
       @new_record  = true
       @destroyed   = false
@@ -383,13 +383,13 @@ module ActiveRecord
     # accessible, even on destroyed records, but cloned models will not be
     # frozen.
     def freeze
-      @attributes = @attributes.clone.freeze
+      @raw_attributes = @raw_attributes.clone.freeze
       self
     end
 
     # Returns +true+ if the attributes hash has been frozen.
     def frozen?
-      @attributes.frozen?
+      @raw_attributes.frozen?
     end
 
     # Allows sort on objects
@@ -418,9 +418,9 @@ module ActiveRecord
 
     # Returns the contents of the record as a nicely formatted string.
     def inspect
-      # We check defined?(@attributes) not to issue warnings if the object is
+      # We check defined?(@raw_attributes) not to issue warnings if the object is
       # allocated but not initialized.
-      inspection = if defined?(@attributes) && @attributes
+      inspection = if defined?(@raw_attributes) && @raw_attributes
                      self.class.column_names.collect { |name|
                        if has_attribute?(name)
                          "#{name}: #{attribute_for_inspect(name)}"
@@ -496,11 +496,11 @@ module ActiveRecord
 
     def init_internals
       pk = self.class.primary_key
-      @attributes[pk] = nil unless @attributes.key?(pk)
+      @raw_attributes[pk] = nil unless @raw_attributes.key?(pk)
 
       @aggregation_cache        = {}
       @association_cache        = {}
-      @attributes_cache         = {}
+      @attributes               = {}
       @readonly                 = false
       @destroyed                = false
       @marked_for_destruction   = false
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 4d63b04d9f..7fb27ef6e9 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -66,7 +66,7 @@ module ActiveRecord
           send(lock_col + '=', previous_lock_value + 1)
         end
 
-        def _update_record(attribute_names = @attributes.keys) #:nodoc:
+        def _update_record(attribute_names = @raw_attributes.keys) #:nodoc:
           return super unless locking_enabled?
           return 0 if attribute_names.empty?
 
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index b74e340b3e..78ae05073a 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -179,8 +179,8 @@ module ActiveRecord
     # So any change to the attributes in either instance will affect the other.
     def becomes(klass)
       became = klass.new
+      became.instance_variable_set("@raw_attributes", @raw_attributes)
       became.instance_variable_set("@attributes", @attributes)
-      became.instance_variable_set("@attributes_cache", @attributes_cache)
       became.instance_variable_set("@changed_attributes", @changed_attributes) if defined?(@changed_attributes)
       became.instance_variable_set("@new_record", new_record?)
       became.instance_variable_set("@destroyed", destroyed?)
@@ -396,11 +396,11 @@ module ActiveRecord
           self.class.unscoped { self.class.find(id) }
         end
 
-      @attributes.update(fresh_object.instance_variable_get('@attributes'))
+      @raw_attributes.update(fresh_object.instance_variable_get('@raw_attributes'))
 
       @column_types           = self.class.column_types
       @column_types_override  = fresh_object.instance_variable_get('@column_types_override')
-      @attributes_cache       = {}
+      @attributes             = {}
       self
     end
 
@@ -490,7 +490,7 @@ module ActiveRecord
 
     # Updates the associated record with values matching those of the instance attributes.
     # Returns the number of affected rows.
-    def _update_record(attribute_names = @attributes.keys)
+    def _update_record(attribute_names = @raw_attributes.keys)
       attributes_values = arel_attributes_with_values_for_update(attribute_names)
       if attributes_values.empty?
         0
@@ -501,7 +501,7 @@ module ActiveRecord
 
     # Creates a record with values matching those of the instance attributes
     # and returns its id.
-    def _create_record(attribute_names = @attributes.keys)
+    def _create_record(attribute_names = @raw_attributes.keys)
       attributes_values = arel_attributes_with_values_for_create(attribute_names)
 
       new_id = self.class.unscoped.insert attributes_values
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index 228b2aa60f..293189fa69 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -95,7 +95,7 @@ module ActiveRecord
       @hash_rows ||=
         begin
           # We freeze the strings to prevent them getting duped when
-          # used as keys in ActiveRecord::Base's @attributes hash
+          # used as keys in ActiveRecord::Base's @raw_attributes hash
           columns = @columns.map { |c| c.dup.freeze }
           @rows.map { |row|
             # In the past we used Hash[columns.zip(row)]
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 17d1ae1ba0..d733063f5a 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -347,7 +347,7 @@ module ActiveRecord
         @_start_transaction_state[:destroyed] = @destroyed
       end
       @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
-      @_start_transaction_state[:frozen?] = @attributes.frozen?
+      @_start_transaction_state[:frozen?] = @raw_attributes.frozen?
     end
 
     # Clear the new record state and id of a record.
@@ -368,16 +368,16 @@ module ActiveRecord
         if transaction_level < 1 || force
           restore_state = @_start_transaction_state
           was_frozen = restore_state[:frozen?]
-          @attributes = @attributes.dup if @attributes.frozen?
+          @raw_attributes = @raw_attributes.dup if @raw_attributes.frozen?
           @new_record = restore_state[:new_record]
           @destroyed  = restore_state[:destroyed]
           if restore_state.has_key?(:id)
             write_attribute(self.class.primary_key, restore_state[:id])
           else
+            @raw_attributes.delete(self.class.primary_key)
             @attributes.delete(self.class.primary_key)
-            @attributes_cache.delete(self.class.primary_key)
           end
-          @attributes.freeze if was_frozen
+          @raw_attributes.freeze if was_frozen
         end
       end
     end
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index 4c96c2f4fd..38faffb870 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -534,7 +534,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
 
   def test_accessing_cached_attributes_caches_the_converted_values_and_nothing_else
     t = topics(:first)
-    cache = t.instance_variable_get "@attributes_cache"
+    cache = t.instance_variable_get "@attributes"
 
     assert_not_nil cache
     assert cache.empty?
-- 
cgit v1.2.3