Skip to content

Add new Rails/SchemaCommentPresence cop to enforce comments in db/schema.rb #1607

@vbyno

Description

@vbyno

Is your feature request related to a problem? Please describe.

db/schema.rb is the single source of truth for the database structure,
but table and column meanings are often opaque without inline documentation.
PostgreSQL and MySQL both support COMMENT ON TABLE / COMMENT ON COLUMN
that are visible in any DB client, yet nothing enforces their presence in
the schema file.

Describe the solution you'd like

A new Rails/SchemaCommentPresence cop that checks every create_table
call and every column definition inside it in db/schema.rb for a
comment: option.

# bad
create_table 'users', force: :cascade do |t|
  t.string 'email', null: false
end

# good
create_table 'users', force: :cascade, comment: 'Application users' do |t|
  t.string 'email', null: false, comment: 'Login identifier'
end

The cop should be disabled by default and support two configuration
options:

ExcludedTables — skip framework-managed or legacy tables entirely
ExcludedColumns — skip columns by name across all tables (e.g. created_at, updated_at)
Index definitions, t.timestamps, foreign keys, and check constraints
should always be skipped.

Describe alternatives you've considered

Option A — extend Rails/SchemaComment.
The existing cop has no file-path restriction and already handles
create_table + columns, so it could cover db/schema.rb as well.
The changes would be:

  • Add ExcludedTables and ExcludedColumns config options
  • Enhance messages to include the table/column name
  • Scope Include to both migration files and db/schema.rb

Downside: the message change is breaking for anyone relying on the current
message text, and add_column (migrations only) would need careful
handling for the new config options.

Option B — add a new Rails/SchemaCommentPresence cop.
A focused cop scoped exclusively to db/schema.rb. No breaking changes
to Rails/SchemaComment.
Downside: two similarly named cops that overlap
in concept.

I have a working implementation of Option B ready. Happy to go with either
approach — what do the maintainers prefer?

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions