[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8099":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":16,"starSnapshotCount":16,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},8099,"active_record_doctor","gregnavis\u002Factive_record_doctor","gregnavis","Identify database issues before they hit production.","",null,"Ruby",1915,69,14,19,0,1,18.54,"MIT License",false,"master",[23,24,25,26,27],"activerecord","database","performance","rails","ruby","2026-06-12 02:01:49","# Active Record Doctor\n\nActive Record Doctor helps to keep the database in a good shape. Currently, it\ncan detect:\n\n* extraneous indexes - [`active_record_doctor:extraneous_indexes`](#removing-extraneous-indexes)\n* unindexed `deleted_at` columns - [`active_record_doctor:unindexed_deleted_at`](#detecting-unindexed-deleted_at-columns)\n* missing foreign key constraints - [`active_record_doctor:missing_foreign_keys`](#detecting-missing-foreign-key-constraints)\n* models referencing undefined tables - [`active_record_doctor:undefined_table_references`](#detecting-models-referencing-undefined-tables)\n* uniqueness validations not backed by a unique index - [`active_record_doctor:missing_unique_indexes`](#detecting-uniqueness-validations-not-backed-by-an-index)\n* missing non-`NULL` constraints - [`active_record_doctor:missing_non_null_constraint`](#detecting-missing-non-null-constraints)\n* missing presence validations - [`active_record_doctor:missing_presence_validation`](#detecting-missing-presence-validations)\n* incorrect presence validations on boolean columns - [`active_record_doctor:incorrect_boolean_presence_validation`](#detecting-incorrect-presence-validations-on-boolean-columns)\n* mismatches between model length validations and database validation constraints - [`active_record_doctor:incorrect_length_validation`](#detecting-incorrect-length-validation)\n* incorrect values of `dependent` on associations - [`active_record_doctor:incorrect_dependent_option`](#detecting-incorrect-dependent-option-on-associations)\n* primary keys having short integer types - [`active_record_doctor:short_primary_key_type`](#detecting-primary-keys-having-short-integer-types)\n* mismatched foreign key types - [`active_record_doctor:mismatched_foreign_key_type`](#detecting-mismatched-foreign-key-types)\n* tables without primary keys - [`active_record_doctor:table_without_primary_key`](#detecting-tables-without-primary-keys)\n* tables without timestamps - [`active_record_doctor:table_without_timestamps`](#detecting-tables-without-timestamps)\n\nIt can also:\n\n* index unindexed foreign keys - [`active_record_doctor:unindexed_foreign_keys`](#indexing-unindexed-foreign-keys)\n\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Flint.yml\u002Fbadge.svg?branch=master)](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Flint.yml)\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Fmysql.yml\u002Fbadge.svg?branch=master)](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Fmysql.yml)\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Fpostgresql.yml\u002Fbadge.svg?branch=master)](https:\u002F\u002Fgithub.com\u002Fgregnavis\u002Factive_record_doctor\u002Factions\u002Fworkflows\u002Fpostgresql.yml)\n\n## Installation\n\nIn order to use the latest production release, please add the following to\nyour `Gemfile`:\n\n```ruby\ngem 'active_record_doctor', group: [:development, :test]\n```\n\nand run `bundle install`. If you'd like to use the most recent development\nversion then use this instead:\n\n```ruby\ngem 'active_record_doctor', github: 'gregnavis\u002Factive_record_doctor', group: [:development, :test]\n```\n\nThat's it when it comes to Rails projects. If your project doesn't use Rails\nthen you can use `active_record_doctor` via `Rakefile`.\n\n### Additional Installation Steps for non-Rails Projects\n\nIf your project uses Rake then you can add the following to `Rakefile` in order\nto use `active_record_doctor`:\n\n```ruby\nrequire \"active_record_doctor\"\n\nActiveRecordDoctor::Rake::Task.new do |task|\n  # Add project-specific Rake dependencies that should be run before running\n  # active_record_doctor.\n  task.deps = []\n\n  # A path to your active_record_doctor configuration file.\n  task.config_path = ::Rails.root.join(\".active_record_doctor.rb\")\n\n  # A Proc called right before running detectors that should ensure your Active\n  # Record models are preloaded and a database connection is ready.\n  task.setup = -> { ::Rails.application.eager_load! }\nend\n```\n\n**IMPORTANT**. `active_record_doctor` expects that after running `deps` and\ncalling `setup` your Active Record models are loaded and a database connection\nis established.\n\n## Usage\n\n`active_record_doctor` can be used via `rake` or `rails`.\n\nYou can run all available detectors via:\n\n```\nbundle exec rake active_record_doctor\n```\n\nYou can run a specific detector via:\n\n```\nbundle exec rake active_record_doctor:extraneous_indexes\n```\n\n### Continuous Integration\n\nIf you want to use `active_record_doctor` in a Continuous Integration setting\nthen ensure the configuration file is committed and run the tool as one of your\nbuild steps -- it returns a non-zero exit status if any errors were reported.\n\n### Obtaining Help\n\nIf you'd like to obtain help on a specific detector then use the `help`\nsub-task:\n\n```\nbundle exec rake active_record_doctor:extraneous_indexes:help\n```\n\nThis will show the detector help text in the terminal, along with supported\nconfiguration options, their meaning, and whether they're global or local.\n\n### Debug Logging\n\nIt may be that `active_record_doctor` fails with an exception and it is hard to tell\nwhat went wrong. For easier debugging, use `ACTIVE_RECORD_DOCTOR_DEBUG` environment variable.\nIf `active_record_doctor` fails for some reason for your application, feel free\nto open an issue or a PR with the fix.\n\n```\nACTIVE_RECORD_DOCTOR_DEBUG=1 bundle exec rake active_record_doctor\n```\n\n### Configuration\n\n`active_record_doctor` can be configured to better suit your project's needs.\nFor example, if it complains about a model that you want ignored then you can\nadd that model to the configuration file.\n\nIf you want to use the default configuration then you don't have to do anything.\nJust run `active_record_doctor` in your project directory.\n\nIf you want to customize the tool you should create a file named\n`.active_record_doctor.rb` in your project root directory with content like:\n\n```ruby\nActiveRecordDoctor.configure do\n  # Global settings affect all detectors.\n  global :ignore_tables, [\n    # Ignore internal Rails-related tables.\n    \"ar_internal_metadata\",\n    \"schema_migrations\",\n    \"active_storage_blobs\",\n    \"active_storage_attachments\",\n    \"action_text_rich_texts\",\n\n    # Add project-specific tables here.\n    \"legacy_users\"\n  ]\n\n  # Detector-specific settings affect only one specific detector.\n  detector :extraneous_indexes,\n    ignore_tables: [\"users\"],\n    ignore_indexes: [\"accounts_on_email_organization_id\"]\nend\n```\n\nThe configuration file above will make `active_record_doctor` ignore internal\nRails tables (which are ignored by default) and also the `legacy_users` table.\nIt'll also make the `extraneous_indexes` detector skip the `users` table\nentirely and will not report the index named `accounts_on_email_organization_id`\nas extraneous.\n\nConfiguration options for each detector are listed below. They can also be\nobtained via the help mechanism described in the previous section.\n\n### Regexp-Based Ignores\n\nSettings like `ignore_tables`, `ignore_indexes`, `ignore_models` and so on\naccept list of identifiers to ignore. These can be either:\n\n1. Strings - in which case an exact match is needed.\n2. Regexps - which are matched against object names, and matching ones are\n   excluded from output.\n\nFor example, to ignore all tables starting with `legacy_` and all models under\nthe `Legacy::` namespace you can write:\n\n```ruby\nActiveRecordDoctor.configure do\n  global :ignore_tables, [\n    # Ignore all legacy tables.\n    \u002F^legacy_\u002F\n  ]\n  global :ignore_models, [\n    # Ignore all legacy models.\n    \u002F^Legacy::\u002F\n  ]\nend\n```\n\n### Indexing Unindexed Foreign Keys\n\nForeign keys should be indexed unless it's proven ineffective. However, Rails\nmakes it easy to create an unindexed foreign key. Active Record Doctor can\nautomatically generate database migrations that add the missing indexes. It's a\nthree-step process:\n\n1. Generate a list of unindexed foreign keys by running\n\n  ```bash\n  bundle exec rake active_record_doctor:unindexed_foreign_keys > unindexed_foreign_keys.txt\n  ```\n\n2. Remove columns that should _not_ be indexed from `unindexed_foreign_keys.txt`\n   as a column can look like a foreign key (i.e. ending with `_id`) without being\n   one.\n\n3. Generate the migrations\n\n  ```bash\n  rails generate active_record_doctor:add_indexes unindexed_foreign_keys.txt\n  ```\n\n4. Run the migrations\n\n  ```bash\n  bundle exec rake db:migrate\n  ```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose foreign keys should not be checked\n- `ignore_columns` - columns, written as table.column, that should not be\n  checked.\n\n### Removing Extraneous Indexes\n\nLet me illustrate with an example. Consider a `users` table with columns\n`first_name` and `last_name`. If there are two indexes:\n\n* A two-column index on `last_name, first_name`.\n* A single-column index on `last_name`.\n\nThen the latter index can be dropped as the former can play its role. In\ngeneral, a multi-column index on `column_1, column_2, ..., column_n` can replace\nindexes on:\n\n* `column_1`\n* `column_1, column_2`\n* ...\n* `column_1, column_2, ..., column_(n - 1)`\n\nTo discover such indexes automatically just follow these steps:\n\n1. List extraneous indexes by running:\n\n  ```bash\n  bundle exec rake active_record_doctor:extraneous_indexes\n  ```\n\n2. Confirm that each of the indexes can be indeed dropped.\n\n3. Create a migration to drop the indexes.\n\nThe indexes aren't dropped automatically because there are usually just a few of\nthem and it's a good idea to double-check that you won't drop something\nnecessary.\n\nAlso, extra indexes on primary keys are considered extraneous too and will be\nreported.\n\nNote that a unique index can _never be replaced by a non-unique one_. For\nexample, if there's a unique index on `users.login` and a non-unique index on\n`users.login, users.domain` then the tool will _not_ suggest dropping\n`users.login` as it could violate the uniqueness assumption. However, a unique\nindex on `users.login, user.domain` might be replaceable with `users.login` as\nthe uniqueness of the latter implies the uniqueness of the former (if a given\n`login` can appear only once then it can be present in only one `login, domain`\npair).\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose indexes should never be reported as extraneous.\n- `ignore_indexes` - indexes that should never be reported as extraneous.\n\n### Detecting Unindexed `deleted_at` Columns\n\nIf you soft-delete some models (e.g. with `paranoia`) then you need to modify\nyour indexes to include only non-deleted rows. Otherwise they will include\nlogically non-existent rows. This will make them larger and slower to use. Most\nof the time they should only cover columns satisfying `deleted_at IS NULL` (to\ncover existing records) or `deleted_at IS NOT NULL` (to cover deleted records).\n\n`active_record_doctor` can automatically detect indexes on tables with a\n`deleted_at` column. Just run:\n\n```\nbundle exec rake active_record_doctor:unindexed_deleted_at\n```\n\nThis will print a list of indexes that don't have the `deleted_at IS NULL`\nclause. Currently, `active_record_doctor` cannot automatically generate\nappropriate migrations. You need to do that manually.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose indexes should not be checked.\n- `ignore_columns` - specific columns, written as table.column, that should not\n  be reported as unindexed.\n- `ignore_indexes` - specific indexes that should not be reported as excluding a\n  timestamp column.\n- `column_names` - deletion timestamp column names.\n\n### Detecting Missing Foreign Key Constraints\n\nIf `User` defines a `belongs_to` association to `Profile` then the underlying\ncolumn (`users.profile_id` by convention) should be marked as a foreign key in\nthe database. If it's not then it's possible to end up in a situation where a\nuser is referencing a non-existent profile.\n\n`active_record_doctor` can automatically detect foreign keys that could benefit\nfrom a foreign key constraint (a future version will generate a migration that\nadd the constraint; for now, it's your job). You can obtain the list of missing\nforeign key constraints with the following command:\n\n```bash\nbundle exec rake active_record_doctor:missing_foreign_keys\n```\n\nIn order to add a foreign key constraint to `users.profile_id` use a migration\nlike:\n\n```ruby\nclass AddForeignKeyConstraintToUsersProfileId \u003C ActiveRecord::Migration\n  def change\n    add_foreign_key :users, :profiles\n  end\nend\n```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose associations should not be checked.\n- `ignore_associations` - associations, written as Model.association, that\n  should not be checked.\n\n### Detecting Models Referencing Undefined Tables\n\nActive Record guesses the table name based on the class name. There are a few\ncases where the name can be wrong (e.g. you forgot to commit a migration or\nchanged the table name). Active Record Doctor can help you identify these cases\nbefore they hit production.\n\n**IMPORTANT**. Models backed by views are supported only in:\n\n* Rails 5+ and _any_ database or\n* Rails 4.2 with PostgreSQL.\n\nThe only thing you need to do is run:\n\n```\nbundle exec rake active_record_doctor:undefined_table_references\n```\n\nIf there a model references an undefined table then you'll see a message like\nthis:\n\n```\nContract references a non-existent table or view named contract_records\n```\n\nOn top of that `rake` will exit with a status code of 1. This allows you to use\nthis check as part of your Continuous Integration pipeline.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose underlying tables should not be checked for\n  existence.\n\n### Detecting Uniqueness Validations not Backed by an Index\n\nModel-level uniqueness validations, `has_one` and `has_and_belongs_to_many`\nassociations should be backed by a database index in order to be robust.\nOtherwise you risk inserting duplicate values under a heavy load.\n\nIn order to detect such validations run:\n\n```\nbundle exec rake active_record_doctor:missing_unique_indexes\n```\n\nIf there are such indexes then the command will print:\n\n```\nadd a unique index on users(email) - validating uniqueness in the model without an index can lead to duplicates\n```\n\nThis means that you should create a unique index on `users.email`.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose uniqueness validators should not be checked.\n- `ignore_columns` - specific validators, written as Model(column1, ...), that\n  should not be checked.\n- `ignore_join_tables` - join tables that should not be checked for existence\n  of unique indexes.\n\n### Detecting Missing Non-`NULL` Constraints\n\nIf there's an unconditional presence validation on a column then it should be\nmarked as non-`NULL`-able at the database level or should have a `IS NOT NULL`\nconstraint. Timestamp columns are also expected to be made `NOT NULL` as they're\nmanaged automatically by Active Record.\n\nIn order to detect columns whose presence is required but that are marked\n`null: true` in the database run the following command:\n\n```\nbundle exec rake active_record_doctor:missing_non_null_constraint\n```\n\nThe output of the command is similar to:\n\n```\nadd `NOT NULL` to users.name - models validates its presence but it's not non-NULL in the database\n```\n\nYou can mark the columns mentioned in the output as `null: false` by creating a\nmigration and calling `change_column_null`.\n\nThis validator skips models whose corresponding database tables don't exist.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose columns should not be checked.\n- `ignore_columns` - columns, written as table.column, that should not be\n  checked.\n\n### Detecting Missing Presence Validations\n\nIf a column is marked as `null: false` then it's likely it should have the\ncorresponding presence validator or an appropriately configured inclusion or\nexclusion validation.\n\nIn order to detect models lacking these validations run:\n\n```\nbundle exec rake active_record_doctor:missing_presence_validation\n```\n\nThe output of the command looks like this:\n\n```\nadd a `presence` validator to User.email - it's NOT NULL but lacks a validator\nadd a `presence` validator to User.name - it's NOT NULL but lacks a validator\n```\n\nThis means `User` should have a presence validator on `email` and `name`.\n\nThis validator skips models whose corresponding database tables don't exist.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose underlying tables' columns should not be checked.\n- `ignore_attributes` - specific attributes, written as Model.attribute, that\n  should not be checked.\n- `ignore_columns_with_default` - set to `true` to ignore columns with default values.\n\n### Detecting Incorrect Presence Validations on Boolean Columns\n\nA boolean column's presence should be validated using inclusion or exclusion\nvalidators instead of the usual presence validator.\n\nIn order to detect boolean columns whose presence is validated incorrectly run:\n\n```\nbundle exec rake active_record_doctor:incorrect_boolean_presence_validation\n```\n\nThe output of the command looks like this:\n\n```\nreplace the `presence` validator on User.active with `inclusion` - `presence` can't be used on booleans\n```\n\nThis means `active` is validated with `presence: true` instead of\n`inclusion: { in: [true, false] }` or `exclusion: { in: [nil] }`.\n\nThis validator skips models whose corresponding database tables don't exist.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose validators should not be checked.\n- `ignore_columns` - attributes, written as Model.attribute, whose validators\n  should not be checked.\n\n### Detecting Incorrect Length Validations\n\nString length can be enforced by both the database and the application. If\nthere's a database limit then it's a good idea to add a model validation to\nensure user-friendly error messages. Similarly, if there's a model validator\nwithout the corresponding database constraint then it's a good idea to add one\nto avoid saving invalid models.\n\nIn order to detect columns whose length isn't validated properly run:\n\n```\nbundle exec rake active_record_doctor:incorrect_length_validation\n```\n\nThe output of the command looks like this:\n\n```\nset the maximum length in the validator of User.email (currently 32) and the database limit on users.email (currently 64) to the same value\nadd a length validator on User.address to enforce a maximum length of 64 defined on users.address\n```\n\nThe first message means the validator on `User.email` is checking for a\ndifferent maximum than the database limit on `users.email`. The second message\nmeans there's a database limit on `users.address` without the corresponding\nmodel validation.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose validators should not be checked.\n- `ignore_attributes` - attributes, written as Model.attribute, whose validators\n  should not be checked.\n\n### Detecting Incorrect `dependent` Option on Associations\n\nCascading model deletions can be sped up with `dependent: :delete_all` (to\ndelete all dependent models with one SQL query) but only if the deleted models\nhave no callbacks as they're skipped.\n\nThis can lead to two types of errors:\n\n- Using `delete_all` when dependent models define callbacks - they will NOT be\n  invoked.\n- Using `destroy` when dependent models define no callbacks - dependent models\n  will be loaded one by one with no reason\n\nIn order to detect associations affected by the two aforementioned problems run\nthe following command:\n\n```\nbundle exec rake active_record_doctor:incorrect_dependent_option\n```\n\nThe output of the command looks like this:\n\n```\nuse `dependent: :delete_all` or similar on Company.users - associated models have no validations and can be deleted in bulk\nuse `dependent: :destroy` or similar on Post.comments - the associated model has callbacks that are currently skipped\n```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_models` - models whose associations should not be checked.\n- `ignore_associations` - associations, written as Model.association, that should not\n  be checked.\n\n### Detecting Primary Keys Having Short Integer Types\n\nActive Record 5.1 changed the default primary and foreign key type from INTEGER\nto BIGINT. The reason is to reduce the risk of running out of IDs on inserts.\n\nIn order to detect primary keys using shorter integer types, for example created\nbefore migrating to 5.1, you can run the following command:\n\n```\nbundle exec rake active_record_doctor:short_primary_key_type\n```\n\nThe output of the command looks like this:\n\n```\nchange the type of companies.id to bigint\n```\n\nThe above means `companies.id` should be migrated to a wider integer type. An\nexample migration to accomplish this looks like this:\n\n```ruby\nclass ChangeCompaniesPrimaryKeyType \u003C ActiveRecord::Migration[5.1]\n  def change\n    change_column :companies, :id, :bigint\n  end\nend\n```\n\n**IMPORTANT**. Running the above migration on a large table can cause downtime\nas all rows need to be rewritten.\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose primary keys should not be checked.\n\n### Detecting Mismatched Foreign Key Types\n\nForeign keys should be of the same type as the referenced primary key.\nOtherwise, there's a risk of bugs caused by IDs representable by one type but\nnot the other.\n\nRunning the command below will list all foreign keys whose type is different\nfrom the referenced primary key:\n\n```\nbundle exec rake active_record_doctor:mismatched_foreign_key_type\n```\n\nThe output of the command looks like this:\n\n```\ncompanies.user_id references a column of a different type - foreign keys should be of the same type as the referenced column\n```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose foreign keys should not be checked.\n- `ignore_columns` - foreign keys, written as table.column, that should not be\n  checked.\n\n### Detecting Tables Without Primary Keys\n\nTables should have primary keys. Otherwise, it becomes problematic to easily find a specific record,\nlogical replication in PostgreSQL will be troublesome, because all the rows need to be unique\nin the table then etc.\n\nRunning the command below will list all tables without primary keys:\n\n```\nbundle exec rake active_record_doctor:table_without_primary_key\n```\n\nThe output of the command looks like this:\n\n```\nadd a primary key to companies\n```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose primary key existence should not be checked\n\n### Detecting Tables Without Timestamps\n\nTables should have timestamp columns (`created_at`\u002F`updated_at`). Otherwise, it becomes problematic\nto easily find when the record was created\u002Fupdated, if the table is active or can be removed,\nautomatic Rails cache expiration after record updates is not possible.\n\nRunning the command below will list all tables without default timestamp columns:\n\n```\nbundle exec rake active_record_doctor:table_without_timestamps\n```\n\nThe output of the command looks like this:\n\n```\nadd a created_at column to companies\n```\n\nSupported configuration options:\n\n- `enabled` - set to `false` to disable the detector altogether\n- `ignore_tables` - tables whose timestamp columns existence should not be checked\n\n## Ruby and Rails Compatibility Policy\n\nThe goal of the policy is to ensure proper functioning in reasonable\ncombinations of Ruby and Rails versions. Specifically:\n\n1. If a Rails version is officially supported by the Rails Core Team then it's\n   supported by `active_record_doctor`.\n2. If a Ruby version is compatible with a supported Rails version then it's\n   also supported by `active_record_doctor`.\n3. Only the most recent teeny Ruby versions and patch Rails versions are supported.\n\n## Author\n\nThis gem is developed and maintained by [Greg Navis](http:\u002F\u002Fwww.gregnavis.com).\n","Active Record Doctor 是一个用于识别数据库潜在问题的工具，确保在生产环境部署前数据库处于良好状态。它支持检测冗余索引、未索引的`deleted_at`列、缺失的外键约束等多种常见数据库问题，并能够自动为未索引的外键创建索引。该工具基于Ruby开发，专为使用ActiveRecord作为ORM层的应用程序设计，特别是那些基于Rails框架构建的应用。通过集成到开发和测试环境中，Active Record Doctor可以帮助开发者及时发现并修复数据库结构上的缺陷，从而提高应用性能与数据一致性。适用于任何希望增强数据库健康状况检查流程的Ruby on Rails项目。",2,"2026-06-11 03:16:05","top_language"]