/schema_plus_indexes

Adds shorthands and conveniences to ActiveRecord's handling of indexes

Primary LanguageRubyMIT LicenseMIT

Gem Version Build Status Coverage Status

SchemaPlus::Indexes

SchemaPlus::Indexes adds various convenient capabilities to ActiveRecord's index handling.

SchemaPlus::Indexes is part of the SchemaPlus family of Ruby on Rails extension gems.

Installation

As usual:

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

Features

Migrations:

Shorthand to define a column with an index:

t.string :role,             index: true     # shorthand for index: {}

Shorthand to define a column with a unique index:

t.string :product_code,     index: :unique  # shorthand for index: { unique: true }

Create multi-column indexes as part of column definition

Adds an option to include other columns in the index:

t.string :first_name
t.string :last_name,        index: { with: :first_name }

t.string :country_code
t.string :area_code
t.string :local_number,     index: { with: [:country_code, :area_code] }

Create indexes with add_column, change_table

ActiveRecord supports the index: option to column definitions when creating table. SchemaPlus::Indexes extends that to work also with add_column and in change_table

add_column "tablename", "columnname", index: { ... }

change_table :tablename do |t|
  t.integer :column,    index: true
end

These of course accept the shorthands and with: option described above.

Remove index :if_exists

remove_index "tablename", "columnname", if_exists: true

Models

SchemaPlus::Indexes lets you easily get the indexes of a model:

Model.indexes  # shorthand for `connection.indexes(Model.table_name)`

The value gets cached until the next time Model.reset_column_information is called.

Other things...

  • Provides consistent behavior regarding attempted duplicate index creation: Ignore and log a warning. Different versions of Rails with different db adapters otherwise behave inconsistently: some ignore the attempt, some raise an error.

  • In the schema dump schema.rb, index definitions are included within the create_table statements rather than added afterwards

  • When using SQLite3, makes sure that the definitions returned by connection.indexes properly include the column orders (:asc or :desc)

  • For the ActiveRecord::ConnectionAdapters::IndexDefinition class (the object that's returned by connection.indexes), SchemaPlus::Indexes:

    • Provides an == operator to compare if two objects refer to an equivalent index
    • Allows calling new with a signature that matches add_index: IndexDefinition.new(table_name, column_names, options)
    • Fleshes out the :orders attribute, listing :asc for a column instead of leaving it undefined.
    • Prevents errors from a down :change migration attempting to remove an index that wasn't previously added (this can arise, e.g. with auto-indexing plugins).

Compatibility

schema_plus_indexes 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

Release Notes

v1.0.1

  • Add AR 6.1 and 7.0 support
  • Add Ruby 3.1 support

v1.0.0

  • Drop AR < 5.2 and add 6.0 support
  • Drop Ruby < 2.5 and add Ruby 3.0 support
  • Remove its-it GEM

v0.3.1

v0.3.0

v0.2.4

  • Supports AR 5.0. Thanks to @myabc

v0.2.3

  • Missing require

v0.2.2

  • Explicit gem dependencies

v0.2.1

  • Upgrade to schema_plus_core 1.0 and conform

v0.2.0

  • Prevent down :change migrations from failing due to trying to remove non-existent indexes

v0.1.0

  • Initial release, extracted from schema_plus 1.x

Development & Testing

Are you interested in contributing to schema_plus_indexes? 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: SchemaPlus::Indexes 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_plus_core: SchemaPlus::Indexes uses the SchemaPlus::Core API that provides middleware callback stacks to make it easy to extend ActiveRecord's behavior. If that API is missing something you need for your contribution, please head over to schema_plus_core and open an issue or pull request.
  • schema_monkey: SchemaPlus::Indexes is implemented as a schema_monkey client, using schema_monkey's convention-based protocols for extending ActiveRecord and using middleware stacks.