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.rb146
1 files changed, 82 insertions, 64 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index c28374e4ab..8fcac82a0d 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -1,11 +1,11 @@
-require 'set'
+require "set"
module ActiveRecord
module AttributeMethods
module PrimaryKey
extend ActiveSupport::Concern
- # Returns this record's primary key value wrapped in an Array if one is
+ # Returns this record's primary key value wrapped in an array if one is
# available.
def to_key
sync_with_transaction_state
@@ -45,84 +45,102 @@ module ActiveRecord
attribute_was(self.class.primary_key)
end
- protected
-
- def attribute_method?(attr_name)
- attr_name == 'id' || super
+ def id_in_database
+ sync_with_transaction_state
+ attribute_in_database(self.class.primary_key)
end
- module ClassMethods
- def define_method_attribute(attr_name)
- super
+ private
- if attr_name == primary_key && attr_name != 'id'
- generated_attribute_methods.send(:alias_method, :id, primary_key)
- end
+ def attribute_method?(attr_name)
+ attr_name == "id" || super
end
- ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was).to_set
+ module ClassMethods
+ def define_method_attribute(attr_name)
+ super
- def dangerous_attribute_method?(method_name)
- super && !ID_ATTRIBUTE_METHODS.include?(method_name)
- end
+ if attr_name == primary_key && attr_name != "id"
+ generated_attribute_methods.send(:alias_method, :id, primary_key)
+ end
+ 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 unless defined? @primary_key
- @primary_key
- end
+ ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database).to_set
- # Returns a quoted version of the primary key name, used to construct
- # SQL statements.
- def quoted_primary_key
- @quoted_primary_key ||= connection.quote_column_name(primary_key)
- end
+ def dangerous_attribute_method?(method_name)
+ super && !ID_ATTRIBUTE_METHODS.include?(method_name)
+ end
- def reset_primary_key #:nodoc:
- if self == base_class
- self.primary_key = get_primary_key(base_class.name)
- else
- self.primary_key = base_class.primary_key
+ # 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 unless defined? @primary_key
+ @primary_key
+ end
+
+ # Returns a quoted version of the primary key name, used to construct
+ # SQL statements.
+ def quoted_primary_key
+ @quoted_primary_key ||= connection.quote_column_name(primary_key)
end
- end
- def get_primary_key(base_name) #:nodoc:
- if base_name && primary_key_prefix_type == :table_name
- base_name.foreign_key(false)
- elsif base_name && primary_key_prefix_type == :table_name_with_underscore
- base_name.foreign_key
- else
- if ActiveRecord::Base != self && table_exists?
- connection.schema_cache.primary_keys(table_name)
+ def reset_primary_key #:nodoc:
+ if self == base_class
+ self.primary_key = get_primary_key(base_class.name)
else
- 'id'
+ self.primary_key = base_class.primary_key
end
end
- end
- # 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
- # def self.primary_key
- # 'foo_' + super
- # end
- # end
- #
- # Project.primary_key # => "foo_id"
- def primary_key=(value)
- @primary_key = value && value.to_s
- @quoted_primary_key = nil
- @attributes_builder = nil
+ def get_primary_key(base_name) #:nodoc:
+ if base_name && primary_key_prefix_type == :table_name
+ base_name.foreign_key(false)
+ elsif base_name && primary_key_prefix_type == :table_name_with_underscore
+ base_name.foreign_key
+ else
+ if ActiveRecord::Base != self && table_exists?
+ pk = connection.schema_cache.primary_keys(table_name)
+ suppress_composite_primary_key(pk)
+ else
+ "id"
+ end
+ end
+ end
+
+ # 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
+ # def self.primary_key
+ # 'foo_' + super
+ # end
+ # end
+ #
+ # Project.primary_key # => "foo_id"
+ def primary_key=(value)
+ @primary_key = value && value.to_s
+ @quoted_primary_key = nil
+ @attributes_builder = nil
+ end
+
+ private
+
+ def suppress_composite_primary_key(pk)
+ return pk unless pk.is_a?(Array)
+
+ warn <<-WARNING.strip_heredoc
+ WARNING: Active Record does not support composite primary key.
+
+ #{table_name} has composite primary key. Composite primary key is ignored.
+ WARNING
+ end
end
- end
end
end
end