Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a migration to remove an index only if it exists, rather than throwing an exception if it doesn't?

Right now, the current migration might fail, if the books table doesn't have created_at or updated_at fields:

class AddTimestampIndexes < ActiveRecord::Migration   def up     remove_index :books, :created_at     remove_index :books, :updated_at      add_index  :books, :created_at     add_index  :books, :updated_at   end    def down     remove_index :books, :created_at     remove_index :books, :updated_at   end end 

Does remove_index take any options to silently proceed if it fails to remove the index rather than raising an error?

like image 701
TheFooProgrammer Avatar asked Feb 15 '14 08:02

TheFooProgrammer


People also ask

How do I migrate a specific migration in Rails?

To run a specific migration up or down, use db:migrate:up or db:migrate:down . The version number in the above commands is the numeric prefix in the migration's filename. For example, to migrate to the migration 20160515085959_add_name_to_users. rb , you would use 20160515085959 as the version number.

What is index in migration?

Migration is the process by which Content Manager OnDemand moves index data from the database to archive storage. Migration optimizes database storage space while allowing you to maintain index data for a very long time.

Does removing column delete index?

16, removing the column removes the index.


2 Answers

You can use the index_exists? method within your migration to test whether the index you need to remove is actually there.

Take a look at the documentation here: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/index_exists%3F

I've not tested it, but you should be able to use something like this:

class AddTimestampIndexes < ActiveRecord::Migration   def up     remove_index :books, :created_at if index_exists?(:books, :created_at)     remove_index :books, :updated_at if index_exists?(:books, :updated_at)      add_index  :books, :created_at     add_index  :books, :updated_at   end    def down     remove_index :books, :created_at     remove_index :books, :updated_at   end end 

Although, by the looks of things, you really only want to create them if they don't exist? This might be more appropriate for your migration:

class AddTimestampIndexes < ActiveRecord::Migration   def up     add_index  :books, :created_at unless index_exists?(:books, :created_at)     add_index  :books, :updated_at unless index_exists?(:books, :updated_at)   end    def down     remove_index :books, :created_at     remove_index :books, :updated_at   end end 
like image 83
Jon Avatar answered Sep 20 '22 17:09

Jon


There is also index_name_exists?(table_name, index_name) method which let's you check for an index by it's name. It's helpful for checking for existence of multi-column indexes.

Documentation - index_name_exists

like image 30
dvvrt Avatar answered Sep 19 '22 17:09

dvvrt