Skip to content

Generate model-aware fixtures - #116

Merged
nertzy merged 1 commit into
masterfrom
model-aware-fixture-generation
Oct 13, 2026
Merged

nertzy merged 1 commit into
masterfrom
model-aware-fixture-generation

Conversation

@nertzy

@nertzy nertzy commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

Fixture generation currently treats every configured table as raw SQL. That leaves Rails without enough model information to reload generated fixtures for models whose constants do not follow the conventional table-name inference.

This foundation resolves eligible Active Record models by their configured table names and writes Rails-native _fixture.model_class metadata for model-backed output. It preserves raw-SQL behavior when no eligible model is available, including tables without usable primary keys and models on another connection pool.

It also organizes tests into one concrete case per file, with path-matching namespaces under test/builder/, test/configuration/, and test/model_resolver/. The top-level test/fixture_builder_test.rb retains integration coverage through the public API, and recursive discovery includes the nested suites. Isolated model-backed tests own their ephemeral schemas with with_model. The development dependency requires with_model 2.5, whose table(false) lets abstract models and models that map to an existing table skip creating an unused table of their own.

This replaces the earlier draft stack in #112, #113, and #115, which are now closed. The dependent follow-up migrates the remaining ordinary fixture tests to the same ownership model.

The configuration tests added in #122 and #125 now use the same pattern: the fixture-output digest test declares its model with with_model, and neither file opens its own in-memory connection. Opening one left later with_model tests creating tables on a different connection than the one they queried.

Models defined inside a migration class are ignored during resolution, so the throwaway models that data migrations define for the tables they backfill no longer tie with the application model and raise AmbiguousModelError.

Explicit fixture names now follow each model's primary key, including custom and composite keys. This also fixes an existing bug: records with UUID or other string id values silently lost their explicit names, because the namer stored the name under the string id but looked it up with id.to_i. test/builder/primary_key_naming_test.rb covers string, composite, and UUID keys.

Closes #109
Closes #72
Closes #49
Closes #124
Closes #129

@nertzy
nertzy force-pushed the model-aware-fixture-generation branch from 3cb10a2 to e0e3f4e Compare September 8, 2026 00:44
@nertzy
nertzy marked this pull request as ready for review September 8, 2026 16:23
@nertzy
nertzy force-pushed the model-aware-fixture-generation branch 7 times, most recently from 52af7ba to 2de7c3f Compare September 12, 2026 23:44
Copilot AI balanced review requested due to automatic review settings October 12, 2026 17:32
@nertzy
nertzy force-pushed the model-aware-fixture-generation branch from 2de7c3f to d53a416 Compare October 12, 2026 17:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Non-isolated fixture loading currently fails, and custom-primary-key models lose explicit fixture labels.

2 open findings
What changed in this PR

Adds model-aware fixture generation while preserving raw SQL fallback for ineligible tables.

Changes:

  • Resolves eligible Active Record models by table name, pool, and primary key.
  • Emits Rails _fixture.model_class metadata and detects ambiguous models.
  • Reorganizes and expands isolated fixture-generation tests.
File Description
lib/​fixture_builder/​model_resolver.rb Implements model resolution.
lib/​fixture_builder/​ambiguous_model_error.rb Adds deterministic ambiguity errors.
lib/​fixture_builder/​builder.rb Generates model-aware fixtures and metadata.
lib/​fixture_builder.rb Loads the new error type.
fixture_builder.gemspec Adds with_model for tests.
README.md Documents model-aware fixtures.
CHANGELOG.md Records the new behavior.
doc/​plans/​2026-08-29-maintainer-backlog-triage.md Updates implementation plans.
test/​test_helper.rb Adds isolated fixture filesystem support.
test/​support/​test_database.rb Reuses and resets the shared database.
test/​support/​model_resolver_ambiguity_behavior.rb Shares ambiguity assertions.
test/​fixture_builder_test.rb Retains public API integration coverage.
test/​fixtures_path_test.rb Extracts fixture-path tests.
test/​configuration_test.rb Extracts configuration tests.
test/​configuration/​manifest_test.rb Isolates manifest coverage.
test/​configuration/​generated_file_marker_test.rb Reuses the shared connection.
test/​configuration/​fixture_output_digest_test.rb Uses an ephemeral model.
test/​configuration/​factories_test.rb Avoids dumping unrelated tables.
test/​builder/​table_name_test.rb Covers configured table names.
test/​builder/​serialization_test.rb Covers model serialization.
test/​builder/​raw_sql_test.rb Covers raw SQL fallback.
test/​builder/​metadata_test.rb Covers Rails fixture metadata.
test/​builder/​generated_fixture_ownership_test.rb Preserves the connection pool.
test/​builder/​generated_columns_test.rb Covers generated model columns.
test/​model_resolver/​table_name_test.rb Tests model-backed versus raw extraction.
test/​model_resolver/​sti_test.rb Tests STI root resolution.
test/​model_resolver/​selection_test.rb Tests resolver eligibility rules.
test/​model_resolver/​ambiguous_model_error_test.rb Tests error attributes and ordering.
test/​model_resolver/​ambiguity/​alphabetical_definition_order_test.rb Tests ambiguity ordering.
test/​model_resolver/​ambiguity/​reverse_alphabetical_definition_order_test.rb Tests reverse definition ordering.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/test_helper.rb
Comment on lines +85 to +88
fixture_set.create_fixtures(fixture_directory, table_names, {}, &block)
end
else
fixture_set.create_fixtures(test_path("fixtures"), table_names, {}, &block)
fixture_set.create_fixtures(fixture_directory, table_names, {}, &block)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applicable: NamerTest loads its fixtures with ActiveRecord::FixtureSet.create_fixtures directly, not through this helper. Every caller of the create_fixtures helper (the generated-columns, metadata, raw SQL, and resolver selection tests) prepends IsolatedFixtureFilesystem, so fixture_directory is always defined.

Comment on lines +35 to +36
primary_keys = Array(model.primary_key).compact
primary_keys.any? && primary_keys.all? { |key| model.columns_hash.key?(key) }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ce787cd. The namer now builds its keys from each table's primary key: name uses model_object.id, record_name takes the primary key column(s) from the builder (falling back to id for raw SQL tables), and populate_custom_names uses the fixture model's primary key. Values compare as strings, so typecast and raw values match and composite keys compare element by element. test/builder/primary_key_naming_test.rb covers a string primary key and a composite key; both lost their explicit names before the change.

@nertzy
nertzy force-pushed the model-aware-fixture-generation branch from d53a416 to 4059339 Compare October 12, 2026 17:45
@nertzy
nertzy force-pushed the model-aware-fixture-generation branch from 4059339 to 66189f1 Compare October 12, 2026 18:10
@nertzy
nertzy force-pushed the model-aware-fixture-generation branch 3 times, most recently from add2531 to ce787cd Compare October 13, 2026 22:13
@nertzy
nertzy force-pushed the model-aware-fixture-generation branch from ce787cd to 3b345fe Compare October 13, 2026 22:17
@nertzy
nertzy merged commit e98181e into master Oct 13, 2026
10 checks passed
@nertzy
nertzy deleted the model-aware-fixture-generation branch October 13, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants