ActiveRecord Migrations

Episode #95 by Teacher's Avatar David Kimura

Summary

This episode covers different tips and tricks around database migration files.
rails database migration 12:00

Resources

Summary

# 20170828000400_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :first_name
      t.string :last_name
      t.string :email_address
      t.string :address_line_one
      t.string :address_line_two
      t.string :address_city
      t.string :address_state
      t.integer :address_zip

      t.timestamps
    end
  end
end

# 20170828002007_add_indexesto_users.rb
class AddIndexestoUsers < ActiveRecord::Migration[5.1]
  def up
    execute <<~SQL
    ALTER TABLE users
    ADD INDEX index_users_on_first_name (first_name),
    ADD INDEX index_users_on_last_name (last_name),
    ADD INDEX index_users_on_email_address (email_address),
    ADD INDEX index_users_on_address_zip (address_zip), 
    ALGORITHM = INPLACE,
    LOCK = NONE
    SQL
  end

  # def change
  #   change_table :users, bulk: true do |t|
  #     t.index :first_name, algorithm: :inplace
  #     t.index :last_name, algorithm: :inplace
  #     t.index :email_address, algorithm: :inplace
  #     t.index :address_zip, algorithm: :inplace
  #   end
  # end

  # def up
  #   add_index :users, :first_name
  #   add_index :users, :last_name
  #   add_index :users, :email_address
  #   add_index :users, :address_zip
  # end

  def down
    # raise ActiveRecord::IrreversibleMigration
    remove_index :users, :first_name
    remove_index :users, :last_name
    remove_index :users, :email_address
    remove_index :users, :address_zip
  end
end

# db/seeds.rb
columns = %w(first_name last_name email_address address_line_one address_line_two address_city address_state address_zip)
count = 1_000_000
slice = 1_000
count.times.each_slice(slice) do |group|
  users = []
  group.each do |iteration|
    users << [].tap do |user|
      user << Faker::Name.first_name
      user << Faker::Name.last_name
      user << Faker::Internet.email
      user << Faker::Address.street_address
      user << Faker::Address.secondary_address
      user << Faker::Address.city
      user << Faker::Address.state_abbr
      user << Faker::Address.zip_code.to_i
    end
  end
  User.import columns, users
  puts "Imported #{group.first + slice} users"
end

# Terminal
rails g model user first_name:string{16} last_name:string email_address:string address_line_one address_line_two address_city address_state:string{2} address_zip:integer

rails db:migrate
rake db:seed

rails g migration AddIndexestoUsers
rails db:migrate
rails db:rollback
rails db:migrate db:rollback
rails db:migrate:down VERSION=20170828002007