Skip to content

Commit

Permalink
Allow primary_key: association option to be composite
Browse files Browse the repository at this point in the history
Association's `primary_key` can be composite when derived from associated class
`primary_key` or `query_constraints`. But we don't allow setting it explicitly
even though Rails is already capable of supporting it.

This commit allows `primary_key` association option to be an array.
  • Loading branch information
nvasilevski committed Mar 18, 2024
1 parent 83a0132 commit cc4f368
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
6 changes: 5 additions & 1 deletion activerecord/lib/active_record/reflection.rb
Expand Up @@ -870,7 +870,11 @@ def association_class
# klass option is necessary to support loading polymorphic associations
def association_primary_key(klass = nil)
if primary_key = options[:primary_key]
@association_primary_key ||= -primary_key.to_s
@association_primary_key ||= if primary_key.is_a?(Array)
primary_key.map { |pk| pk.to_s.freeze }.freeze
else
-primary_key.to_s
end
elsif (klass || self.klass).has_query_constraints? || options[:query_constraints]
(klass || self.klass).composite_query_constraints_list
elsif (klass || self.klass).composite_primary_key?
Expand Down
Expand Up @@ -371,6 +371,18 @@ def test_building_the_belonging_object_for_composite_primary_key
assert_equal id, cpk_book.order_id
end

def test_belongs_to_with_explicit_composite_primary_key
cpk_book = cpk_books(:cpk_great_author_first_book)
order = cpk_book.build_order_explicit_fk_pk
order.shop_id = 123
cpk_book.save

shop_id, id = order.id
assert_equal id, cpk_book.order_id
assert_equal shop_id, cpk_book.shop_id
assert_equal order, cpk_book.reload.order_explicit_fk_pk
end

def test_belongs_to_with_inverse_association_for_composite_primary_key
author = Cpk::Author.new(name: "John")
book = author.books.build(id: [nil, 1], title: "The Rails Way")
Expand Down
1 change: 1 addition & 0 deletions activerecord/test/models/cpk/book.rb
Expand Up @@ -6,6 +6,7 @@ class Book < ActiveRecord::Base

self.table_name = :cpk_books
belongs_to :order, autosave: true, query_constraints: [:shop_id, :order_id], counter_cache: true
belongs_to :order_explicit_fk_pk, class_name: "Cpk::Order", query_constraints: [:shop_id, :order_id], primary_key: [:shop_id, :id]
belongs_to :author, class_name: "Cpk::Author"

has_many :chapters, query_constraints: [:author_id, :book_id]
Expand Down

0 comments on commit cc4f368

Please sign in to comment.