aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-12-01 21:55:59 +0000
committerJon Leighton <j@jonathanleighton.com>2011-12-01 23:41:51 +0000
commite9fb6d04bdfbe3dfc4ba1a3cf442ec5d25764300 (patch)
tree9e6bb6b8c7fbcc4cdcf3cea1e5cacaf6c846ee54 /activerecord
parentf1a534af98950efd9969deea1540717c4516d673 (diff)
downloadrails-e9fb6d04bdfbe3dfc4ba1a3cf442ec5d25764300.tar.gz
rails-e9fb6d04bdfbe3dfc4ba1a3cf442ec5d25764300.tar.bz2
rails-e9fb6d04bdfbe3dfc4ba1a3cf442ec5d25764300.zip
Add test for read_attribute(:id) with non-standard PK.
Also make it actually work. It slows down all read_attribute accesses to map 'id' to whatever the PK actually is, inside read_attribute. So instead make sure the necessary methods are defined and that they redirect wherever they need to go.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb14
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb8
-rw-r--r--activerecord/test/cases/primary_keys_test.rb5
3 files changed, 23 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 98aa1ed225..c756924186 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -25,6 +25,20 @@ module ActiveRecord
end
module ClassMethods
+ def define_method_attribute(attr_name)
+ super
+
+ if attr_name == primary_key && attr_name != 'id'
+ generated_attribute_methods.send(:alias_method, :id, primary_key)
+ generated_attribute_methods.module_eval <<-CODE, __FILE__, __LINE__
+ def self.attribute_id(v, attributes, attributes_cache, attr_name)
+ attr_name = '#{primary_key}'
+ send(:'attribute_#{attr_name}', attributes[attr_name], attributes, attributes_cache, attr_name)
+ end
+ CODE
+ end
+ end
+
def dangerous_attribute_method?(method_name)
super && !['id', 'id=', 'id?'].include?(method_name)
end
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 41cd194c92..2fe9968faf 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -58,7 +58,7 @@ module ActiveRecord
#{internal}
end
- def self.attribute_#{attr_name}(v, attributes_cache, attr_name)
+ def self.attribute_#{attr_name}(v, attributes, attributes_cache, attr_name)
#{external}
end
STR
@@ -68,7 +68,7 @@ module ActiveRecord
eval(internal)
end
- singleton_class.send(:define_method, "attribute_#{attr_name}") do |v, attributes_cache, attr_name|
+ singleton_class.send(:define_method, "attribute_#{attr_name}") do |v, attributes, attributes_cache, attr_name|
eval(external)
end
end
@@ -117,8 +117,8 @@ module ActiveRecord
methods = self.class.generated_attribute_methods
if methods.respond_to?(accessor)
- if @attributes.has_key?(attr_name)
- methods.send(accessor, @attributes[attr_name], @attributes_cache, attr_name)
+ if @attributes.has_key?(attr_name) || attr_name == 'id'
+ methods.send(accessor, @attributes[attr_name], @attributes, @attributes_cache, attr_name)
end
elsif !self.class.attribute_methods_generated?
# If we haven't generated the caster methods yet, do that and
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index cc8ffb5f27..8d248c3f9f 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -23,6 +23,11 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_equal keyboard.to_key, [keyboard.id]
end
+ def test_read_attribute_with_custom_primary_key
+ keyboard = Keyboard.create!
+ assert_equal keyboard.key_number, keyboard.read_attribute(:id)
+ end
+
def test_to_key_with_primary_key_after_destroy
topic = Topic.find(1)
topic.destroy