diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index b891b2c50ec99dba21188ed177030759bfc16088..978cd7fbe346e37d8c6df7399dc834ba6fb41a13 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -14,11 +14,13 @@ module ClassMethods # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the # primary_key_prefix_type setting, though. def primary_key - reset_primary_key + @primary_key ||= reset_primary_key end def reset_primary_key #:nodoc: - key = get_primary_key(base_class.name) + key = self == base_class ? get_primary_key(base_class.name) : + base_class.primary_key + set_primary_key(key) key end @@ -40,6 +42,9 @@ def get_primary_key(base_name) #:nodoc: end end + attr_accessor :original_primary_key + attr_writer :primary_key + # Sets the name of the primary key column to use to the given value, # or (if the value is nil or false) to the value returned by the given # block. @@ -48,9 +53,11 @@ def get_primary_key(base_name) #:nodoc: # set_primary_key "sysid" # end def set_primary_key(value = nil, &block) - define_attr_method :primary_key, value, &block + @primary_key ||= '' + self.original_primary_key = @primary_key + value &&= value.to_s + self.primary_key = block_given? ? instance_eval(&block) : value end - alias :primary_key= :set_primary_key end end end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index e186b2aea7890e2abc0cc3a1bf1d483f74b46012..09ef04a656474aa1870aba3854a71f9931bf99af 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1073,10 +1073,14 @@ def test_define_attr_method_with_value end def test_define_attr_method_with_block - k = Class.new( ActiveRecord::Base ) - k.primary_key = "id" - k.send(:define_attr_method, :primary_key) { "sys_" + original_primary_key } - assert_equal "sys_id", k.primary_key + k = Class.new( ActiveRecord::Base ) do + class << self + attr_accessor :foo_key + end + end + k.foo_key = "id" + k.send(:define_attr_method, :foo_key) { "sys_" + original_foo_key } + assert_equal "sys_id", k.foo_key end def test_set_table_name_with_value diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index c3da9cdf538026637d9eacf8f58a0a41db0969ce..6abbe45492c652fd3e3dc0f3597ca27693486521 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -219,6 +219,10 @@ def test_alt_eager_loading switch_to_default_inheritance_column end + def test_inherits_custom_primary_key + assert_equal Subscriber.primary_key, SpecialSubscriber.primary_key + end + def test_inheritance_without_mapping assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132") assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = 'roger'; s.save }