Active Record Doctor

repository·master·Indexed 23 days ago

https://github.com/gregnavis/active_record_doctor

A tool for maintaining database health in Rails and non-Rails projects by detecting common issues. It identifies missing indexes, mismatched constraints, incorrect model validations, and redundant indexes. Features include detectors for unindexed foreign keys, missing non-NULL constraints, incorrect boolean presence validations, and mismatched foreign key types.

Tokens
6.6K
Snippets
21
Records
42
Agent score
80%

What's inside active_record_doctor

  1. Ruby and Rails Compatibility Policy

    master

    The active_record_doctor gem maintains compatibility based on the following rules:

    1. Any Rails version officially supported by the Rails Core Team is supported by active_record_doctor.
    2. Any Ruby version compatible with a supported Rails version is supported.
    3. Support is limited to the most recent teeny Ruby versions and patch Rails versions.
  2. Detect missing non-NULL constraints

    master

    Identifies columns that have presence validations in the model but are marked as null: true in the database. Also checks that timestamp columns are NOT NULL.

    Usage:

    bundle exec rake active_record_doctor:missing_non_null_constraint

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_tables (list): Tables whose columns should not be checked.
    • ignore_columns (list): Columns, written as table.column, to ignore.
    bundle exec rake active_record_doctor:missing_non_null_constraint
  3. Detect incorrect presence validations on boolean columns

    master

    Identifies boolean columns using presence: true instead of inclusion or exclusion validators. presence cannot be used on booleans because false is considered blank.

    Usage:

    bundle exec rake active_record_doctor:incorrect_boolean_presence_validation

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_models (list): Models whose validators should not be checked.
    • ignore_columns (list): Attributes, written as Model.attribute, to ignore.
    bundle exec rake active_record_doctor:incorrect_boolean_presence_validation
  4. Detect mismatched foreign key types

    master

    Identifies foreign keys that are of a different type than the primary key they reference, which can cause bugs.

    Usage:

    bundle exec rake active_record_doctor:mismatched_foreign_key_type

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_tables (list): Tables whose foreign keys should not be checked.
    • ignore_columns (list): Foreign keys, written as table.column, to ignore.
    bundle exec rake active_record_doctor:mismatched_foreign_key_type
  5. Detect tables without primary keys

    master

    Identifies tables that lack a primary key, which can cause issues with record lookup and logical replication.

    Usage:

    bundle exec rake active_record_doctor:table_without_primary_key

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_tables (list): Tables whose primary key existence should not be checked.
    bundle exec rake active_record_doctor:table_without_primary_key
  6. Obtain help for a specific detector

    master

    If you need to see the supported configuration options and help text for a specific detector, use the :help sub-task. This will display the detector's help text, supported options, their meanings, and whether they are global or local.

    bundle exec rake active_record_doctor:extraneous_indexes:help
  7. Detect incorrect length validations

    master

    Identifies mismatches between model-level string length validations and database-level column limits, or missing model validations for existing database limits.

    Usage:

    bundle exec rake active_record_doctor:incorrect_length_validation

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_models (list): Models whose validators should not be checked.
    • ignore_attributes (list): Attributes, written as Model.attribute, to ignore.
    bundle exec rake active_record_doctor:incorrect_length_validation
  8. Detect models referencing undefined tables

    master

    Identifies models that reference tables or views that do not exist in the database. This is useful for catching missing migrations.

    Compatibility:

    • Rails 5+ (any database)
    • Rails 4.2 (PostgreSQL only)

    Usage:

    bundle exec rake active_record_doctor:undefined_table_references

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_models (list): Models whose underlying tables should not be checked.
    bundle exec rake active_record_doctor:undefined_table_references
  9. Remove extraneous indexes

    master

    A multi-column index on column_1, column_2, ..., column_n can replace individual indexes on column_1, column_1, column_2, etc. Use this detector to find redundant indexes.

    Workflow:

    1. List extraneous indexes:
      bundle exec rake active_record_doctor:extraneous_indexes
    2. Manually confirm each index can be safely dropped.
    3. Create a migration to drop the indexes.

    Note: Unique indexes are never suggested for removal if they could be replaced by a non-unique index, as this would violate uniqueness constraints. Extra indexes on primary keys are also reported.

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_tables (list): Tables whose indexes should never be reported.
    • ignore_indexes (list): Specific indexes that should never be reported.
    bundle exec rake active_record_doctor:extraneous_indexes
  10. Detect primary keys with short integer types

    master

    Identifies primary keys using shorter integer types (e.g., INTEGER) instead of BIGINT. This is relevant for projects migrating to or following the Active Record 5.1+ default.

    Usage:

    bundle exec rake active_record_doctor:short_primary_key_type

    Warning: Running migrations to change primary key types on large tables can cause downtime as all rows must be rewritten.

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_tables (list): Tables whose primary keys should not be checked.
    bundle exec rake active_record_doctor:short_primary_key_type
  11. Detect incorrect `dependent` option on associations

    master

    Identifies two types of association errors:

    1. Using dependent: :delete_all when the dependent models define callbacks (callbacks will be skipped).
    2. Using dependent: :destroy when the dependent models have no callbacks (unnecessary overhead of loading models one-by-one).

    Usage:

    bundle exec rake active_record_doctor:incorrect_dependent_option

    Supported configuration options:

    • enabled (boolean): Set to false to disable the detector.
    • ignore_models (list): Models whose associations should not be checked.
    • ignore_associations (list): Associations, written as Model.association, to ignore.
    bundle exec rake active_record_doctor:incorrect_dependent_option
  12. Install Active Record Doctor in non-Rails projects

    master

    If your project uses Rake but does not use Rails, you can integrate active_record_doctor by adding a new task to your Rakefile using ActiveRecordDoctor::Rake::Task.new.

    Important: You must ensure that after running the deps and the setup proc, your Active Record models are loaded and a database connection is established.

    require "active_record_doctor"
    
    ActiveRecordDoctor::Rake::Task.new do |task|
      # Add project-specific Rake dependencies that should be run before running
      # active_record_doctor.
      task.deps = []
    
      # A path to your active_record_doctor configuration file.
      task.config_path = ::Rails.root.join(".active_record_doctor.rb")
    
      # A Proc called right before running detectors that should ensure your Active
      # Record models are preloaded and a database connection is ready.
      task.setup = -> { ::Rails.application.eager_load! }
    end