From 362134b4628aa1604dfd6660e99b4c0b0b8e6996 Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Fri, 1 Sep 2023 13:33:46 -0500 Subject: [PATCH 1/2] [skip ci] Document composite primary key behaviour Adds documentation to exaplain composite key behaviour in ActiveRecord::AttributeMethods::PrimaryKey for methods #id, #id=, #id?, #id_before_type_cast, #id_was, #id_in_database. --- .../attribute_methods/primary_key.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 57719f543a796..4adee074e9948 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -15,7 +15,8 @@ def to_key Array(key) if key end - # Returns the primary key column's value. + # Returns the primary key column's value. If the primary key is composite, + # returns an array of the primary key column values. def id return _read_attribute(@primary_key) unless @primary_key.is_a?(Array) @@ -28,7 +29,8 @@ def primary_key_values_present? # :nodoc: !!id end - # Sets the primary key column's value. + # Sets the primary key column's value. If the primary key is composite, + # raises TypeError when the set value not enumerable. def id=(value) if self.class.composite_primary_key? raise TypeError, "Expected value matching #{self.class.primary_key.inspect}, got #{value.inspect}." unless value.is_a?(Enumerable) @@ -38,7 +40,8 @@ def id=(value) end end - # Queries the primary key column's value. + # Queries the primary key column's value. If the primary key is composite, + # all primary key column values must be queryable. def id? if self.class.composite_primary_key? @primary_key.all? { |col| _query_attribute(col) } @@ -47,7 +50,8 @@ def id? end end - # Returns the primary key column's value before type cast. + # Returns the primary key column's value before type cast. If the primary key is composite, + # returns an array of primary key column values before type cast. def id_before_type_cast if self.class.composite_primary_key? @primary_key.map { |col| attribute_before_type_cast(col) } @@ -56,7 +60,8 @@ def id_before_type_cast end end - # Returns the primary key column's previous value. + # Returns the primary key column's previous value. If the primary key is composite, + # returns an array of primary key column previous values. def id_was if self.class.composite_primary_key? @primary_key.map { |col| attribute_was(col) } @@ -65,7 +70,8 @@ def id_was end end - # Returns the primary key column's value from the database. + # Returns the primary key column's value from the database. If the primary key is composite, + # returns an array of primary key column values from database. def id_in_database if self.class.composite_primary_key? @primary_key.map { |col| attribute_in_database(col) } From 5ae1c5a81217584cb6a2f280991d19935c8f543c Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Fri, 1 Sep 2023 13:52:35 -0500 Subject: [PATCH 2/2] [skip ci] Document id_value method Adds documention for ActiveRecord::ModelSchema#id_value as a utility when using composite primary keys. --- activerecord/lib/active_record/model_schema.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb index 4384ec7c5db7d..71397ed2fab89 100644 --- a/activerecord/lib/active_record/model_schema.rb +++ b/activerecord/lib/active_record/model_schema.rb @@ -6,6 +6,13 @@ module ActiveRecord module ModelSchema extend ActiveSupport::Concern + ## + # :method: id_value + # :call-seq: id_valiue + # + # Returns the underlying column value for a column named "id". Useful when defining + # a composite primary key including an "id" column so that the value is readable. + ## # :singleton-method: primary_key_prefix_type # :call-seq: primary_key_prefix_type