25 AUGUST 2020/RAILS

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

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:

  1. it's less code (you don't have to write the _fixture block)
  2. the DEFAULTS label is easy to spot and explicit. You could use DECISION_DEFAULTS: &decisions instead of decisions: &decisions but the label isn't really useful and, again, you're writing more code than if it's just DEFAULTS: &decisions
Arnaud Joubay

Arnaud Joubay

Swift & Rails Indie Maker. Original Parasider. Time Knight. 11y Remote/WFH. Half of @teambkry. Creator of cows in App Store featured @nomeat_today. Scuba diver.👨‍💻🐕🐋🥐🐮🍉🌱.