From e4c112c84594e90ea71d2caef21fea3d0db6a13f Mon Sep 17 00:00:00 2001 From: Navid EMAD Date: Wed, 3 Jun 2026 15:20:28 +0200 Subject: [PATCH] Document why parent_data is required in ActiveRecordCoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `parent_data` in `#generate` looks removable but is load-bearing, and nothing in the code said why. A child replays its parent's rows by calling `parent.mount` inside the generate block, but those INSERTs go through `execute_batch` tagged "FixtureKit Insert", which the sql.active_record subscriber cannot attribute to a model — so the parent's models never enter `captured_models` on their own. `captured_models.merge(parent_data.keys)` puts them back, keeping the child cache self-contained (mountable without the parent's cache file). Add a comment at the merge site in `#generate` and a pointer at the `execute_batch` tag in `#mount` so a future contributor doesn't drop `parent_data` and quietly break inherited fixtures. Comments only; no behavior change. --- lib/fixture_kit/coders/active_record_coder.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/fixture_kit/coders/active_record_coder.rb b/lib/fixture_kit/coders/active_record_coder.rb index 31b9196..da78965 100644 --- a/lib/fixture_kit/coders/active_record_coder.rb +++ b/lib/fixture_kit/coders/active_record_coder.rb @@ -24,6 +24,16 @@ def generate(parent_data: nil, &block) ActiveSupport::Notifications.subscribed(subscriber, EVENT, monotonic: true, &block) captured_models.map! { |model| base_table_model(model) } + + # parent_data carries the parent fixture's models forward (its keys are the + # parent's models). This is required, not redundant: a child replays its + # parent's rows by calling parent.mount inside the &block above, but those + # INSERTs run through execute_batch tagged "FixtureKit Insert" (see #mount), + # which the subscriber can't attribute to a model — so the parent's models + # never enter captured_models on their own. Merging them here keeps the + # child cache self-contained: it can be mounted without the parent's cache + # file present. Don't drop this without also changing how replayed rows are + # tagged so the subscriber can recapture them. captured_models.merge(parent_data.keys) if parent_data generate_statements(captured_models) @@ -39,6 +49,11 @@ def mount(data) connection.disable_referential_integrity do # execute_batch is private in current supported Rails versions. # This should be revisited when Rails 8.2 makes it public. + # + # The generic "FixtureKit Insert" tag means these replayed INSERTs + # are not attributable to a model by the #generate subscriber. That + # is why inherited fixtures pass parent models forward via parent_data + # rather than recapturing them here (see #generate). connection.__send__(:execute_batch, statements, "FixtureKit Insert") end