aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods/primary_key.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods/primary_key.rb')
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb90
1 files changed, 57 insertions, 33 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 36d7f4ad11..a7785f8786 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -5,16 +5,48 @@ module ActiveRecord
# Returns this record's primary key value wrapped in an Array if one is available
def to_key
- key = send(self.class.primary_key)
+ key = self.id
[key] if key
end
+ # Returns the primary key value
+ def id
+ read_attribute(self.class.primary_key)
+ end
+
+ # Sets the primary key value
+ def id=(value)
+ write_attribute(self.class.primary_key, value)
+ end
+
+ # Queries the primary key value
+ def id?
+ query_attribute(self.class.primary_key)
+ 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_external_attribute_methods.module_eval <<-CODE, __FILE__, __LINE__
+ def id(v, attributes, attributes_cache, attr_name)
+ attr_name = '#{primary_key}'
+ send(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
+
# 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
- @primary_key ||= reset_primary_key
- raise ActiveRecord::UnknownPrimaryKey.new(self) unless @primary_key
+ @primary_key = reset_primary_key unless defined? @primary_key
@primary_key
end
@@ -24,16 +56,11 @@ module ActiveRecord
end
def reset_primary_key #:nodoc:
- key = self == base_class ? get_primary_key(base_class.name) :
- base_class.primary_key
-
- set_primary_key(key)
- key
- end
-
- def primary_key? #:nodoc:
- @primary_key ||= reset_primary_key
- !@primary_key.nil?
+ if self == base_class
+ self.primary_key = get_primary_key(base_class.name)
+ else
+ self.primary_key = base_class.primary_key
+ end
end
def get_primary_key(base_name) #:nodoc:
@@ -45,35 +72,32 @@ module ActiveRecord
when :table_name_with_underscore
base_name.foreign_key
else
- if ActiveRecord::Base != self && connection.table_exists?(table_name)
- connection.primary_key(table_name)
+ if ActiveRecord::Base != self && table_exists?
+ connection.schema_cache.primary_keys[table_name]
else
'id'
end
end
end
- attr_accessor :original_primary_key
-
- # Attribute writer for the primary key column
- def primary_key=(value)
- @quoted_primary_key = nil
- @primary_key = value
- end
-
- # 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.
+ # Sets the name of the primary key column.
+ #
+ # class Project < ActiveRecord::Base
+ # self.primary_key = "sysid"
+ # end
+ #
+ # You can also define the primary_key method yourself:
#
# class Project < ActiveRecord::Base
- # set_primary_key "sysid"
+ # def self.primary_key
+ # "foo_" + super
+ # end
# end
- def set_primary_key(value = nil, &block)
- @quoted_primary_key = nil
- @primary_key ||= ''
- self.original_primary_key = @primary_key
- value &&= value.to_s
- self.primary_key = block_given? ? instance_eval(&block) : value
+ # Project.primary_key # => "foo_id"
+ def primary_key=(value)
+ @original_primary_key = @primary_key if defined?(@primary_key)
+ @primary_key = value && value.to_s
+ @quoted_primary_key = nil
end
end
end