Multiple YAML defaults in Rails fixtures
You know that you can use YAML defaults in your fixtures to extract common attributes values and make your fixtures more readable.
DEFAULTS: &DEFAULTS
created_on: <%= 3.weeks.ago.to_s(:db) %>
first:
name: Smurf
<<: *DEFAULTS
second:
name: Fraggle
<<: *DEFAULTS
What if you want to use more than one set of defaults?
The old way - DEFAULTS
The Rails example is a bit confusing because it uses "DEFAULTS" for both the label and the anchor/alias, but here's how to handle multiple defaults:
DEFAULTS: &decisions
icon: π§
name: Decisions
DEFAULTS: &help
icon: π
name: Help
founders_decisions:
team: founders
<<: *decisions
founders_help_requests:
team: founders
<<: *help
To understand how this works, you need to know two things.
The Rails docs tell us that it doesn't matter how many "DEFAULTS" label we have: they won't overwrite themselves even though they use the same label.
Any fixture labeled βDEFAULTSβ is safely ignored
The YAML spec explains how aliasing works
Repeated nodes (objects) are first identified by an anchor (marked with the ampersand - β&β), and are then aliased (referenced with an asterisk - β*β) thereafter.
Edge Rails way - fixture:ignore
There's another way to do that on Edge Rails. You can specify fixtures that should be ignored and that you can therefore use as defaults.
We can rewrite the example above like this:
_fixture:
ignore:
- decisions
- help
decisions: &decisions
icon: π§
name: Decisions
help: &help
icon: π
name: Help
founders_decisions:
team: founders
<<: *decisions
founders_help_requests:
team: founders
<<: *help
Which one should I use?
If you're using the Rails 6.0.3.2 or below, you don't have a choice anyway. But even then, while the edge option is interesting because the anchor/alias mirrors the label, I'll stick with the "old way" for two reasons:
- it's less code (you don't have to write the _fixture block)
- the DEFAULTS label is easy to spot and explicit. You could use
DECISION_DEFAULTS: &decisions
instead ofdecisions: &decisions
but the label isn't really useful and, again, you're writing more code than if it's justDEFAULTS: &decisions