Organize Rails I18n — YAML structure, lazy lookup in views, absolute keys in helpers and controllers, interpolation and pluralization, datetime/number formats, and Active Record error messages. DHH/37signals style: boring keys, framework-first, no string concatenation in templates. Use when adding or changing locales, extracting user-facing copy from ERB, flash messages, or validation messages; not for translation vendor tooling or SPA i18n-js. Triggers: locales, config/locales YAML, t(), I18n.t, missing translations, flash copy, human_attribute_name.
| Task | Action |
|---|---|
| New feature copy | Read references/patterns.md § Key structure; add keys under a feature namespace |
| Strings in a view | Prefer t(".key") lazy lookup; read § Lazy vs absolute |
| Strings in a helper / shared partial | Absolute key — t("feature.button.save") |
| Flash / controller messages | Absolute keys; keep messages out of fat controllers where possible |
| Validation / attribute labels | activerecord tree — § Active Record |
| Mailer subject / body phrases | mailers.* + § Mailers in patterns; mailer skill § subjects |
| Pluralization / dates / numbers | § Pluralization and datetime; use l(), number_to_* |
Place files under config/locales/ — e.g. en.yml, articles.en.yml. Keep default locale complete for keys you introduce; add secondary locales when the app actually ships them.
Swap "Save", "Cancel", concatenated greetings, etc., for t() calls and keys. Use %{name} — never string math for grammar.
In development, config.i18n.raise_on_missing_translations = true (if enabled) catches missing keys. Run the screen or mailer preview that uses the new copy.
t() / I18n.t, not raw literals (domain data excepted)count: and proper one / other (and locale-specific keys when required)activerecord attributes/errors follow Rails structure for forms