shimgo
10/2/2016 - 6:19 AM

rails DB関連まとめ

rails DB関連まとめ

DBコンソールの起動

rails db

railsで使うDBの作成

rake db:create

環境指定してDBを作成

rake db:create RAILS_ENV=production

マイグレーション履歴の確認

bundle exec rake db:migrate:status

Statusが up :DBに反映済み
down :DBに反映されていない

マイグレーションの削除

  • まだDBに反映していない場合
bundle exec rake db:migrate:status

でStatusがdownになっていればそのマイグレーションファイルを削除するだけでマイグレーション履歴から削除される。

  • DBに反映している場合
bundle exec rake db:migrate:status

でStatusがupになっている場合、以下のコマンドでロールバックしてdownにする必要がある。

bundle exec rake db:migrate:down VERSION=[downさせたいmigration ID]

Statusがdownになったらマイグレーションファイルを削除すればマイグレーション履歴から削除される。

  • DBに反映しているマイグレーションファイルを削除してしまった場合
bundle exec rake db:migrate:status

でStatusがupでMigration NameがNO FILEになってしまった場合、downができなくなる。
なので手でファイルを作ってNO FILEを解消する。

touch [NO FILEのマイグレーションID]_tmp.rb

中身は以下のようにする。

class Tmp < ActiveRecord::Migration
  def change
  end
end

Statusを確認するとMigration NameがTmpになっているはず。
後はTmpのStatusを以下のコマンドでdownにする。

bundle exec rake db:migrate:down VERSION=[Tmpのmigration ID]

Statusがdownになったらマイグレーションファイルを削除すればマイグレーション履歴から削除される。

指定できる型の一覧

binary
boolean
date
datetime
decimal
float
integer
primary_key
string
text
time
timestamp

マイグレーションファイルで外部キーを設定する

class CreateProjects < ActiveRecord::Migration
  def change
    create_table :projects do |t|
      t.references :company, foreign_key: true
    end
  end
end

referencesだけだとdb:migrateしてもDBに外部キーは設定されない。
また、1つのテーブルに1つのテーブルを参照する複数の外部キーを設定する場合にはadd_foreign_keyを使わないと設定できない。

class CreateMessages < ActiveRecord::Migration
  def change
    create_table :messages do |t|
      t.references :sender
      t.references :recipient
    end
    add_foreign_key :messages, :users, column: :sender_id
    add_foreign_key :messages, :users, column: :recipient_id
  end
end

カラム追加時

add_reference :tweets, :user, foreign_key: true

外部キー追加時にインデックス名が長すぎた場合

t.references :user, index: {:name => "index_my_shorter_name"}

関連削除

remove_reference :estimates, :tariff_type, foreign_key: true, null: false, after: :client_id

後からNOT NULL制約を追加する

2は、デフォルト値が設定されていないカラムではNOT NULLにしたときにエラーにならないように 2に更新してから制約を追加する。列のデフォルト値になるわけではない

change_column_null :tweets, :user_id, false, 2

既にデータが入っているテーブルに、新規作成したマスタテーブルへの外部キーとなるカラムを追加するが、追加時の初期値をカラムのデフォルト値設定にせずに指定した値にする

    create_table :administrator_statuses do |t|
      t.string :name, null: false
      t.timestamps
    end
    
    AdministratorStatus.find_or_initialize_by(id:  1).update!(name: "作成後")
    add_column :administrators, :administrator_status_id, :bigint, after: :name
    change_column_null :administrators, :administrator_status_id, false, 1
    add_foreign_key :administrators, :administrator_statuses

add_referenceバージョン

  def up
    add_reference :administrators, :administrator_status, foreign_key: true, after: :id
    change_column_null :administrators, :administrator_status_id, false, 1
  end

  def down
    remove_reference :administrators, :administrator_status
  end

カラムの追加位置を指定する

usersテーブルphoneカラムの後ろにmobile_phoneカラムを追加する場合

add_column :users, :mobile_phone, :string, after: :phone

null制約の追加・削除

change_column_null :users, :nickname, true

コメントの追加・削除

change_column_comment(:users, :name, 'フルネーム')
change_column_comment(:users, :name, nil)

テーブル名の変更

rename_table :list_users, :editabilities 

カラム名の変更

rename_column :users, :nickname, :username

カラムの削除

型を書かないとロールバックできなくなるので注意

remove_column :users, :uid, :string

インデックスの追加・削除、ユニーク制約の追加

# 追加
add_index :users, :name

# ユニーク制約追加
add_index :users, :name, :unique => true

# 削除
remove_index :users, :name

# 複合インデックスの場合
add_index :users, [:name, :name2]

既に追加済みのユニークインデックスの一意成約のみ取り除く

remove_index :users, :login_id
add_index :users, :login_id

カラムの追加コマンド

rails g migration AddColumnToUser full_name:string

カラムの削除コマンド

rails generate migration RemoveAuthorFromTitles author:string

ロールバック

rake db:rollback

double型

add_column :table_name, :column, :float, limit: 53

デフォルト値変更

change_column_default :products, :recommended, from: false, to: true