Skip to content

Commit

Permalink
Merge pull request #47810 from Shopify/pm/fixture-id
Browse files Browse the repository at this point in the history
Generate unique members of a composite key in fixtures
  • Loading branch information
eileencodes committed Mar 30, 2023
2 parents e8b47dd + f7062f2 commit 82fca55
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
22 changes: 18 additions & 4 deletions activerecord/lib/active_record/fixture_set/table_row.rb
Expand Up @@ -87,7 +87,7 @@ def fill_row_model_attributes
return unless model_class
fill_timestamps
interpolate_label
generate_primary_key
model_class.composite_primary_key? ? generate_composite_primary_key : generate_primary_key
resolve_enums
resolve_sti_reflections
end
Expand Down Expand Up @@ -117,14 +117,28 @@ def interpolate_label
end

def generate_primary_key
# generate a primary key if necessary
Array(model_metadata.primary_key_name).each do |pk|
next if !model_metadata.has_column?(pk) || @row.include?(pk)
pk = model_metadata.primary_key_name

unless column_defined?(pk)
@row[pk] = ActiveRecord::FixtureSet.identify(@label, model_metadata.column_type(pk))
end
end

def generate_composite_primary_key
id = ActiveRecord::FixtureSet.identify(@label)
model_metadata.primary_key_name.each_with_index do |column, index|
next if column_defined?(column)
raise "Automatic key generation assumes columns of type Integer." unless model_metadata.column_type(column) == :integer

# Shift label identifier index-#-of-times to differentiate sub-components in deterministic manner.
@row[column] = (id << index) % ActiveRecord::FixtureSet::MAX_ID
end
end

def column_defined?(col)
!model_metadata.has_column?(col) || @row.include?(col)
end

def resolve_enums
reflection_class.defined_enums.each do |name, values|
if @row.include?(name)
Expand Down
15 changes: 14 additions & 1 deletion activerecord/test/cases/fixtures_test.rb
Expand Up @@ -1643,13 +1643,26 @@ def readonly_config
end

class CompositePkFixturesTest < ActiveRecord::TestCase
fixtures :cpk_orders, :cpk_books
fixtures :cpk_orders, :cpk_books, :authors

def test_generates_composite_primary_key_for_partially_filled_fixtures
david = authors(:david)
david_cpk_book = cpk_books(:cpk_known_author_david_book)

assert_not_empty(david_cpk_book.id.compact)
assert_equal david.id, david_cpk_book.author_id
assert_not_nil david_cpk_book.number
end

def test_generates_composite_primary_key_ids
assert_not_empty(cpk_orders(:cpk_groceries_order_1).id.compact)

assert_not_nil(cpk_books(:cpk_great_author_first_book).author_id)
assert_not_nil(cpk_books(:cpk_great_author_first_book).number)
end

def test_generates_composite_primary_key_with_unique_components
assert_equal 2, cpk_orders(:cpk_groceries_order_1).id.uniq.size
end
end
end
5 changes: 5 additions & 0 deletions activerecord/test/fixtures/cpk_books.yml
Expand Up @@ -12,3 +12,8 @@ cpk_great_author_second_book:
cpk_famous_author_first_book:
title: "Ruby on Rails"
revision: 1

cpk_known_author_david_book:
author_id: 1
title: "David's CPK Book"
revision: 1

0 comments on commit 82fca55

Please sign in to comment.