You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document coders, FK verification, and PK sequence reset in reference
Reflects v0.15.0 (Coder concept + register API) and v0.16.0
(FK verification gate, batched + per-table sequence reset) in the
canonical in-repo reference.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/reference.md
+57-1Lines changed: 57 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,8 +7,9 @@ Canonical API, configuration, and contract reference.
7
7
-**Definition**: `FixtureKit.define { ... }` returns a `FixtureKit::Definition`.
8
8
-**Fixture**: wraps an identifier and a definition; handles cache save/mount.
9
9
-**Cache**: persists and replays SQL for touched models.
10
+
-**Coder**: decides what gets cached during generate and how to replay it on mount. `FixtureKit::ActiveRecordCoder` is registered by default; additional coders can be registered to capture state outside ActiveRecord.
10
11
-**Repository**: exposes records via methods, loaded lazily and memoized per test.
11
-
-**Runner**: owns configuration, registry, startup state, and adapter instance.
12
+
-**Runner**: owns configuration, registry, startup state, and adapter and coder instances.
- Adds a coder class to the registered set. Coder instances are created lazily once per runner and reused across fixtures.
186
+
187
+
## Coder Contract
188
+
189
+
Subclass `FixtureKit::Coder` and implement:
190
+
191
+
`#generate(parent_data: nil, &block)`
192
+
- Called once when fixture cache is being built.
193
+
- Set up observation, then call the block to evaluate the user's fixture definition (and any inner coders).
194
+
- Return data to be cached for this coder. Will be passed to `#encode` before serialization.
195
+
-`parent_data` is the cached data from the same coder on the parent fixture when `extends:` is used; `nil` otherwise.
196
+
197
+
`#mount(data)`
198
+
- Called once per test mount with the data this coder produced. Re-create the state on the test database.
199
+
200
+
`#encode(data)`
201
+
- Convert the in-memory representation produced by `#generate` to a JSON-serializable form. Default: identity.
202
+
203
+
`#decode(data)`
204
+
- Inverse of `#encode`. Default: identity.
205
+
206
+
Coder registration:
207
+
208
+
```ruby
209
+
FixtureKit.configure do |config|
210
+
config.register(MyCoder)
211
+
end
212
+
```
213
+
214
+
Chain semantics:
215
+
- Coders form a chain; outer coders wrap inner coders' generate blocks.
216
+
- The innermost block is the user's `FixtureKit.define` body.
217
+
- Order is determined by registration; `ActiveRecordCoder` is registered first by default.
218
+
219
+
## Foreign Key Verification
220
+
221
+
When `ActiveRecord.verify_foreign_keys_for_fixtures` is `true` (Rails default since 8.0 `load_defaults`), `FixtureKit::ActiveRecordCoder#mount` calls `connection.check_all_foreign_keys_valid!` after replaying cached statements. A violation raises `FixtureKit::Error` with a stale-cache hint.
222
+
223
+
- PostgreSQL and SQLite implement the check.
224
+
- MySQL inherits the abstract no-op.
225
+
226
+
## Primary Key Sequence Reset
227
+
228
+
After replaying cached INSERTs, `FixtureKit::ActiveRecordCoder#mount` resets the primary key sequence for each touched table:
229
+
- Rails 8.2+: `connection.reset_column_sequences!(tables)` in one batched call per connection.
- Adapters that expose neither (MySQL, SQLite): skipped — their PK generators advance from explicit-id INSERTs.
232
+
233
+
This prevents `PG::UniqueViolation` when fixtures are mounted onto a database whose sequence is at its initial value (e.g., parallel test workers with their own DB copies).
0 commit comments