Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions