Low commit activity in last 3 years
No release in over a year
In an ActiveRecord migration, set the default to create a foreign key and index for all columns that define relatoins.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 3.0
~> 13.0
~> 4.2.0

Runtime

 Project Readme

Gem Version Build Status Coverage Status

SchemaAutoForeignKeys

SchemaAutoForeignKeys is part of the SchemaPlus family of Ruby on Rails ActiveRecord extension gems.

Usage

Many of us think that it should goes without saying that if you define a foreign key relation in your database you should also define a foreign key constraint.

Similarly, it should go without saying that if you have a foreign key constraint on a column, you should also have an index on that column.

And if you include the schema_auto_foreign_keys gem, these will also go without typing! schema_auto_foreign_keys simply turns on some default behavior in your migrations:

t.integer :user_id  # any column named xxxx_id defaults to...
t.integer :user_id, foreign_key: true, index: true

t.references :user # references defaults to...
t.references :user, foreign_key: true, index: true

t.belongs_to :user # belongs_to default to...
t.belongs_to :user, foreign_key: true, index: true

Note that schema_auto_foreign_keys depends on the schema_plus_foreign_keys and schema_plus_indexes gems, and so makes available their migration shortcuts.

There is actually one difference between an auto-created index and specifying index: true: if you don't specify anything, schema_auto_foreign_keys will maintain "ownership" of the auto-created index: It will remove the index if the foreign key gets removed; and it will rename the index if the table gets renamed.

Overriding

If you need specific paramaters other than the default, you can of course specify them:

t.integer :user_id, index: :unique  # "has one" relationship between users and this
model
t.integer :user_id, on_delete: :cascade

If you don't want a foreign key constraint (e.g. because "product_id" is a domain-level string rather than a foreign key), or an index just specify falsey:

t.integer :product_id, foreign_key: false # also implies index: false
t.integer :product_id, references: nil
t.integer :user_id, index: false

Configuration

SchemaAutoForeignKeys adds two new entries to SchemaPlus::ForeignKeys' config:

SchemaPlus::ForeignKeys.setup do |config|
   config.auto_create = true # default for schema_auto_foreign_keys
   config.auto_index = true # default for schema_auto_foreign_keys
end

You can also configure the behavior per-table in a migration:

create_table :posts, foreign_keys: { auto_create: true, auto_index: true } do |t|
   t.integer :author_id
endf

Installation

As usual:

gem "schema_auto_foreign_keys"                # in a Gemfile
gem.add_dependency "schema_auto_foreign_keys" # in a .gemspec

Compatibility

SchemaAutoForeignKeys is tested on:

  • ruby 2.5 with activerecord 5.2, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.5 with activerecord 6.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.5 with activerecord 6.1, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.7 with activerecord 5.2, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.7 with activerecord 6.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.7 with activerecord 6.1, using mysql2, sqlite3 or postgresql:9.6
  • ruby 2.7 with activerecord 7.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.0 with activerecord 6.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.0 with activerecord 6.1, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.0 with activerecord 7.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.1 with activerecord 6.0, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.1 with activerecord 6.1, using mysql2, sqlite3 or postgresql:9.6
  • ruby 3.1 with activerecord 7.0, using mysql2, sqlite3 or postgresql:9.6

Platform-specific Notes:

MySQL automatically creates indexes for foreign key constraints, so when used with MySQL, schema_auto_foreign_keys doesn't include the auto-index capability.

SQlite3 doesn't support renaming the auto-index whtn the table name changes.

History

  • 1.1.0 - Add AR 6.1 and 7.0, Add Ruby 3.1. remvoe schema_plus_compatiblity dependency
  • 1.0.0 - Drop Ruby < 2.5 and Rails < 5.2, add Rails 6.0, and remove many deprecations
  • 0.1.3 - AR5 (Rails 5) Support
  • 0.1.2 - Missing require
  • 0.1.1 - Explicit gem dependencies
  • 0.1.0 - Initial release, extracted from schema_plus 2.0.0.pre*

Development & Testing

Are you interested in contributing to SchemaAutoForeignKeys? Thanks! Please follow the standard protocol: fork, feature branch, develop, push, and issue pull request.

Some things to know about to help you develop and test:

  • schema_dev: SchemaAutoForeignKeys uses schema_dev to facilitate running rspec tests on the matrix of ruby, activerecord, and database versions that the gem supports, both locally and on github actions

    To to run rspec locally on the full matrix, do:

      $ schema_dev bundle install
      $ schema_dev rspec
    

    You can also run on just one configuration at a time; For info, see schema_dev --help or the schema_dev README.

    The matrix of configurations is specified in schema_dev.yml in the project root.

  • schema_monkey: SchemaAutoForeignKeys is implemented as a schema_monkey client, using schema_monkey's convention-based protocols for extending ActiveRecord and using middleware stacks.