diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2005-11-02 17:30:59 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2005-11-02 17:30:59 +0000 |
commit | aabf9093a09a825d776b83f7fec6473ad8b75cca (patch) | |
tree | 93eb6544d1b87e7ff7226db389a1fe62eee29e1f /activerecord | |
parent | ac58ba60f6cfc272992129ce28808e37391b95d7 (diff) | |
download | rails-aabf9093a09a825d776b83f7fec6473ad8b75cca.tar.gz rails-aabf9093a09a825d776b83f7fec6473ad8b75cca.tar.bz2 rails-aabf9093a09a825d776b83f7fec6473ad8b75cca.zip |
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.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2850 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord')
-rwxr-xr-x | activerecord/lib/active_record/base.rb | 23 | ||||
-rwxr-xr-x | activerecord/test/base_test.rb | 2 |
2 files changed, 12 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 0d9b1d4f7b..4aaa05a6c9 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1,4 +1,5 @@ require 'yaml' +require 'set' require 'active_record/deprecated_finders' module ActiveRecord #:nodoc: @@ -761,15 +762,14 @@ module ActiveRecord #:nodoc: end end - # Contains the names of the generated reader methods. def read_methods - @read_methods ||= {} + @read_methods ||= Set.new end - + # Resets all the cached information about columns, which will cause them to be reloaded on the next request. def reset_column_information - read_methods.each_key {|name| undef_method(name)} + read_methods.each { |name| undef_method(name) } @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil end @@ -1134,14 +1134,13 @@ module ActiveRecord #:nodoc: yield self if block_given? end - # Every Active Record class must use "id" as their primary ID. This getter overwrites the native - # id method, which isn't being used in this context. + # A model instance's primary key is always available as model.id + # whether you name it the default 'id' or set it to something else. def id attr_name = self.class.primary_key - column = column_for_attribute(attr_name) - raise ActiveRecordError, "No such primary key column #{attr_name} for table #{self.class.table_name}" if column.nil? + column = column_for_attribute(attr_name) define_read_method(:id, attr_name, column) if self.class.generate_read_methods - (value = @attributes[attr_name]) && column.type_cast(value) + read_attribute(attr_name) end # Enables Active Record objects to be used as URL parameters in Action Pack automatically. @@ -1473,17 +1472,17 @@ module ActiveRecord #:nodoc: end end - # Define a column type specific reader method. + # Define an attribute reader method. Cope with nil column. def define_read_method(symbol, attr_name, column) - cast_code = column.type_cast_code('v') + cast_code = column.type_cast_code('v') if column access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']" unless attr_name.to_s == self.class.primary_key.to_s access_code = access_code.insert(0, "raise NoMethodError, 'missing attribute: #{attr_name}', caller unless @attributes.has_key?('#{attr_name}'); ") + self.class.read_methods << attr_name end self.class.class_eval("def #{symbol}; #{access_code}; end") - self.class.read_methods[attr_name] = true unless symbol == :id end # Returns true if the attribute is of a text column and marked for serialization. diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb index 76f442c71c..04307267b0 100755 --- a/activerecord/test/base_test.rb +++ b/activerecord/test/base_test.rb @@ -1079,6 +1079,6 @@ class BasicsTest < Test::Unit::TestCase private def assert_readers(model, exceptions) expected_readers = model.column_names - (model.serialized_attributes.keys + exceptions + ['id']) - assert_equal expected_readers.sort, model.read_methods.keys.sort + assert_equal expected_readers.sort, model.read_methods.to_a.sort end end |