Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 2850

Show
Ignore:
Timestamp:
11/02/05 17:30:59 (3 years ago)
Author:
bitsweat
Message:

Correct reader method generation for primary key attribute: handle case when primary_key is defined but its column is nil, such as when the model class is backed by a view.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/lib/active_record/base.rb

    r2837 r2850  
    11require 'yaml' 
     2require 'set' 
    23require 'active_record/deprecated_finders' 
    34 
     
    762763      end 
    763764 
    764      
    765765      # Contains the names of the generated reader methods. 
    766766      def read_methods 
    767         @read_methods ||= {} 
    768       end 
    769        
     767        @read_methods ||= Set.new 
     768      end 
     769 
    770770      # Resets all the cached information about columns, which will cause them to be reloaded on the next request. 
    771771      def reset_column_information 
    772         read_methods.each_key {|name| undef_method(name)
     772        read_methods.each { |name| undef_method(name)
    773773        @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil 
    774774      end 
     
    11351135      end 
    11361136 
    1137       # Every Active Record class must use "id" as their primary ID. This getter overwrites the native 
    1138       # id method, which isn't being used in this context
     1137      # A model instance's primary key is always available as model.id 
     1138      # whether you name it the default 'id' or set it to something else
    11391139      def id 
    11401140        attr_name = self.class.primary_key 
    1141         column    = column_for_attribute(attr_name) 
    1142         raise ActiveRecordError, "No such primary key column #{attr_name} for table #{self.class.table_name}" if column.nil? 
     1141        column = column_for_attribute(attr_name) 
    11431142        define_read_method(:id, attr_name, column) if self.class.generate_read_methods 
    1144         (value = @attributes[attr_name]) && column.type_cast(value) 
     1143        read_attribute(attr_name) 
    11451144      end 
    11461145 
     
    14741473      end 
    14751474 
    1476       # Define a column type specific reader method
     1475      # Define an attribute reader method.  Cope with nil column
    14771476      def define_read_method(symbol, attr_name, column) 
    1478         cast_code = column.type_cast_code('v') 
     1477        cast_code = column.type_cast_code('v') if column 
    14791478        access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']" 
    14801479 
    14811480        unless attr_name.to_s == self.class.primary_key.to_s 
    14821481          access_code = access_code.insert(0, "raise NoMethodError, 'missing attribute: #{attr_name}', caller unless @attributes.has_key?('#{attr_name}'); ") 
     1482          self.class.read_methods << attr_name 
    14831483        end 
    14841484 
    14851485        self.class.class_eval("def #{symbol}; #{access_code}; end") 
    1486         self.class.read_methods[attr_name] = true unless symbol == :id 
    14871486      end 
    14881487 
  • trunk/activerecord/test/base_test.rb

    r2817 r2850  
    10801080    def assert_readers(model, exceptions) 
    10811081      expected_readers = model.column_names - (model.serialized_attributes.keys + exceptions + ['id']) 
    1082       assert_equal expected_readers.sort, model.read_methods.keys.sort 
     1082      assert_equal expected_readers.sort, model.read_methods.to_a.sort 
    10831083    end 
    10841084end