diff --git a/README.md b/README.md index 2d76165..d97f327 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1348 TILs and counting..._ +_1349 TILs and counting..._ --- @@ -775,6 +775,7 @@ _1348 TILs and counting..._ ### Rails - [Add A Check Constraint To A Table](rails/add-a-check-constraint-to-a-table.md) +- [Add A Database Index If It Does Not Already Exist](rails/add-a-database-index-if-it-does-not-already-exist.md) - [Add A Foreign Key Reference To A Table](rails/add-a-foreign-key-reference-to-a-table.md) - [Add A Reference Column With An Index](rails/add-a-reference-column-with-an-index.md) - [Add ActiveRecord Error Not Tied To Any Attribute](rails/add-activerecord-error-not-tied-to-any-attribute.md) diff --git a/rails/add-a-database-index-if-it-does-not-already-exist.md b/rails/add-a-database-index-if-it-does-not-already-exist.md new file mode 100644 index 0000000..e969c64 --- /dev/null +++ b/rails/add-a-database-index-if-it-does-not-already-exist.md @@ -0,0 +1,36 @@ +# Add A Database Index If It Does Not Already Exist + +Sometimes you aren't sure if an index might already exist in one of the +environments where a migration is going to run. But you still need to add the +index elsewhere. One way of handling that is to add an index with the +`if_not_exists` directive. + +```ruby +class AddIndexToEventsCreatedAt < ActiveRecord::Migration[6.1] + def change + add_index :events, :created_at, if_not_exists: true + end +end +``` + +`ActiveRecord` will translate this directive into the resulting SQL statement +like so: + +```sql +create index if not exists index_events_on_created_at on events ... ; +``` + +This way the index will be created in a database where it doesn't already exist +and otherwise the statement will short-circuit rather than erroring when one +does exist. + +A couple notes: + +1) From the PostgreSQL manual: + +> there is no guarantee that the existing index is anything like the one that +> would have been created. + +2) The `if_not_exists` option also works with `create_table`. + +[source](https://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html)