paper-trail-gem/paper_trail · warning
Passing versions association name as `has_paper_trail versio
Error message
Passing versions association name as `has_paper_trail versions: %{versions_name}` is deprecated. Use `has_paper_trail versions: {name: %{versions_name}}` instead. The hash you pass to `versions:` is now passed directly to `has_many`. What it means
has_paper_trail's `versions:` option used to accept a bare symbol/string naming the versions association (`versions: :audit_records`). ensure_versions_option_is_hash in lib/paper_trail/model_config.rb:195 now requires a Hash — the hash is forwarded directly to `has_many` (see the setup at model_config.rb:186-192, which splats `options[:versions].except(:name, :scope)`), so :name and :scope moved inside it. A non-nil non-Hash value triggers this deprecation via PaperTrail.deprecator and is then coerced to `{ name: options[:versions] }`, so current behavior is preserved but the bare form will stop working in a future release.
Source
Thrown at lib/paper_trail/model_config.rb:195
def define_has_many_versions(options)
options = ensure_versions_option_is_hash(options)
check_version_class_name(options)
check_versions_association_name(options)
scope = get_versions_scope(options)
@model_class.has_many(
@model_class.versions_association_name,
scope,
class_name: @model_class.version_class_name,
as: :item,
**options[:versions].except(:name, :scope)
)
end
def ensure_versions_option_is_hash(options)
unless options[:versions].is_a?(Hash)
if options[:versions]
PaperTrail.deprecator.warn(
format(
DPR_PASSING_ASSOC_NAME_DIRECTLY_TO_VERSIONS_OPTION,
versions_name: options[:versions].inspect
),
caller(1)
)
end
options[:versions] = {
name: options[:versions]
}
end
options
end
# Process an `ignore`, `skip`, or `only` option.
def event_attribute_option(option_name)
[@model_class.paper_trail_options[option_name]].
flatten.View on GitHub (pinned to 098058ae47)
Solutions
- Convert the bare value to a hash with the :name key: `has_paper_trail versions: { name: :audit_records }`.
- If you also customize the association scope or other has_many options, put them in the same hash (`versions: { name: :audit_records, scope: -> { order("created_at DESC") } }`) since the hash now goes directly to has_many.
- Sweep the codebase for other models using the shorthand and set `PaperTrail.deprecator.behavior = :raise` in tests so remaining call sites fail CI.
Example fix
# app/models/article.rb - before
has_paper_trail versions: :article_versions
# app/models/article.rb - after
has_paper_trail versions: { name: :article_versions } Defensive patterns
Strategy: validation
Validate before calling
# CI guard: fail if any model passes a bare symbol/string to versions: # grep -rn --include='*.rb' -E 'has_paper_trail[^\n]*versions:\s*:[a-zA-Z_]' app lib && exit 1 || exit 0
Prevention
- Always pass `versions:` as a Hash: `{ name: ... }` for the association name, and any other has_many options alongside it.
- Remember `versions: nil` / `versions: false` do NOT warn (falsy values skip the check), so only truthy bare values are a smell — but be explicit anyway.
- Enable `PaperTrail.deprecator.behavior = :raise` in the test environment so shorthand usage from generators or older models breaks CI immediately.
When it happens
Trigger: Writing `has_paper_trail versions: :my_versions` or `versions: "my_versions"` (any truthy non-Hash) in a model on paper_trail 11+/12+. Fires at boot when ModelConfig#ensure_versions_option_is_hash runs; `versions: nil`, `versions: false`, or an omitted key do NOT warn (the `if options[:versions]` guard).
Common situations: Models upgraded from paper_trail < 11 that renamed the association via the old `versions: :symbol` shorthand; developers mixing the two syntaxes (`versions: { name: :x }` in one model, `versions: :x` in another); code generators or templates still emitting the pre-11 form.
Related errors
- Passing Version class name as `has_paper_trail class_name: %
- PaperTrail %s is not compatible with ActiveRecord %s. We all
- Attribute #{k} does not exist on #{version.item_type} (Versi
AI-assisted analysis of paper-trail-gem/paper_trail@098058ae47 (2026-08-21).
Data as JSON: /api/errors/d3645b56d764bddf.
Report an issue: GitHub.