Rails

基礎Ruby on Rails Chapter4 データベースとモデル

基礎Ruby on Rails Chapter3 レイアウトテンプレート
基礎Ruby on Rails Chapter4 データの保存

データベースの設定

接続の設定

  • DBMSへの接続設定はconfig/database.ymlで行う。
  • rails newコマンドは、DBMSを指定しないとSQLite3用の設定を作る。
config/database.yml
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3

3つのモード

  • 開発 development 開発環境
  • テスト test 自動テストのための環境
  • 本番 production 本番環境

  • database.ymlには、それぞれの環境用の設定が書いてある。

  • config/environmentsディレクトリの下には、3つのモードごとの設定ファイルがある。(develop.rb、test.rb、production.rb)

  • 環境変数によって切り替える。export RAILS_ENV=productionを実行してから、railsコマンドを実行すると、本番モードの下で動く。

データベースの作成

データベースの作成

  • 以下のコマンドで(develop、test環境の)dbを作成する。
  • SQLLite3では自動的にデータベースができるが、MySQLやPostgreSQLでは必須。
$ bin/rails db:create
  • 以下のコマンドで(本番環境の)dbを作成する。
$ bin/rails db:create RAILS_ENV=production
  • 以下のコマンドでdbを削除する。(本番環境ではRAILS_ENV=productionを付ける)
$ bin/rails db:drop

タイムゾーンの設定

config/application.rb(一部)
    # タイムゾーンの設定を追加
    config.time_zone = "Tokyo"
  end
end

モデルの作成

  • モデルを作成するには、bin/rails g model モデル名を実行する。
  • モデル名は複数形にしてはいけない。
  • entry_image、EntryImageとしてもEntryImageモデルができる。テーブル名はentry_images。
$ bin/rails g model member
      invoke  active_record
      create    db/migrate/20180918123930_create_members.rb
      create    app/models/member.rb
model/member.rb
class Member < ApplicationRecord
end

マイグレーション

マイグレーションで、データベースの中にMemberモデルに対応するmembersテーブルを作成する。

マイグレーションスクリプト

  • 上記で作成した、db/migrate/20180918123930_create_members.rbがマイグレーションスクリプト。
db/migrate/20180918123930_create_members.rb
class CreateMembers < ActiveRecord::Migration[5.2]
  def change
    create_table :members do |t|

      t.timestamps
    end
  end
end

membersテーブルの作成

上記スクリプトを以下のように修正する。

db/migrate/20180918123930_create_members.rb
class CreateMembers < ActiveRecord::Migration[5.2]
  def change
    create_table :members do |t|
      t.integer :number, null: false  # 背番号
      t.string :name, null: false # ユーザ名
      t.string :full_name # 本名
      t.string :email # メールアドレス
      t.date :birthday  # 生年月日
      t.integer :sex, null: false, default: 1 # 性別(1:男、2:女)
      t.boolean :administrator, null: false, default: false # 管理者フラグ

      t.timestamps
    end
  end
end
  • migrateは、bin/rails db:migrateコマンドを実行すると、開発用のデータベースにテーブルmembersが作成され、カラムか追加される。
  • 本番環境では、bin/rails db:migrate RAILS_ENV=productionを実行する。
$ bin/rails db:migrate
== 20180918123930 CreateMembers: migrating ====================================
-- create_table(:members)
   -> 0.0018s
== 20180918123930 CreateMembers: migrated (0.0024s) ===========================
  • rb:db/schema.rbに、migrateした時点でのデータベースの構造を再現するスクリプトが書き込まれる。
db/schema.rb
ActiveRecord::Schema.define(version: 2018_09_18_123930) do
  create_table "members", force: :cascade do |t|
    t.integer "number", null: false
    t.string "name", null: false
    t.string "full_name"
    t.string "email"
    t.date "birthday"
    t.integer "sex", default: 1, null: false
    t.boolean "administrator", default: false, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end

マイグレーションの詳細

カラムの追加

  • 以下を実行して、マイグレーションスクリプトを作成する。
$ bin/rails g migration AlterMembers
  • 以下のように、add_column :テーブル名, :カラム名, :カラムの型を追記する。
class AlterMembers < ActiveRecord::Migration[5.2]
  def change
    # 以下を追記する。
    add_column :members, :phone, :string
  end
end
  • bin/rails db:migrateを実行すると、新たに、phoneカラムが追加される。

マイグレーションのバージョン

  • マイグレーションスクリプトのファイル名の「年月日時分秒」は、マイグレーションのバージョンを表す。
  • 古いバージョンに戻したい場合は、以下のようにバージョンを指定する。この前に行った変更が打ち消す操作が行われる。
$ bin/rails db:migrate VERSION=20180523132805
  • マイグレーションのバージョンは、データベースのschema_migrationsテーブルで管理されている。
  • schema_migrationsテーブルは、bin/rails db:migrateコマンドを実行すると自動的に作られる。
  • bin/rails db:migrate:statusコマンドを実行すると、現在のマイグレーションのバージョンを確認できる。upが付いているのが現在のマイグレーション。
$ bin/rails db:migrate:status

database: /mnt/c/Users/tseno/Desktop/rails/asagao/db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20180918123930  Create members
  • データベース定義を古い定義に戻すには、bin/rails db:rollbackコマンドも使える。
  • 以下はマイグレーションを1つだけ取り消す。(ロールバック)
$ bin/rails db:rollback
  • 以下はマイグレーションを3つ戻す。STEPオプションを使う。
$ bin/rails db:rollback STEP=3

カラムの変更と削除

  • マイグレーション用メソッド

    • add_column(テーブル名,カラム名,型,オプション) カラムの追加
    • rename_column(テーブル名,カラム名,新しい名前) カラム名の変更
    • change_column(テーブル名,カラム名,型,オプション) カラムの型の変更
    • remove_column(テーブル名,カラム名) カラムの削除
  • 以下はnameカラムを、nicknameに名前を変更する例。

class AlterMembers < ActiveRecord::Migration
  def change
    rename_column :members, :name, :nickname
  end
end
  • change_columnと、remove_columnは、changeメソッド内で使用すると、ロールバックできない。
    • upメソッドに、マイグレーションを進める処理を書く。
    • downメソッドに、取り消す処理を描く。
class AlterMembers < ActiveRecord::Migration
  def up
    rename_column :members, :name, :nickname
    change_column :members, :sex, :integer, null: false, default:2
  end

  def down
    change_column :members, :sex, :integer, null: false, default:1
    rename_column :members, :nickname, :name
  end
end

インデックス

  • インデックスの作成。add_index :テーブル名, :カラム名, オプション
  • マイグレーションスクリプト、change、up、downメソッドで使用できる。
  • add_indexオプション
    • unique: 重複禁止
    • name: インデックス名(省略すると、テーブル名_カラム名_indexとなる)
add_index :members, :name, unique: true, name: 'name_index'
  • インデックスの削除。columnオプションでカラム名を指定するか、nameオプションでインデックス名を指定する。
remove_index :members, column: 'name'
remove_index :members, name: 'name_index'

開発中と本番でのマイグレーション

開発中にテーブル定義を変更する方法としては以下の2通りがある。

  • 新しいマイグレーションスクリプトを追加し、マイグレーションを行う。
    • 本番稼働中など、データベースの破棄ができない場合
  • 既存のマイグレーションスクリプトを書き換え、マイグレーションを最初からやり直す。
    • マイグレーションを最初からやり直すには、bin/rails db:migrate:resetコマンドを使う。
$ bin/rails db:migrate:reset

参考
改訂4版 基礎 Ruby on Rails (IMPRESS KISO SERIES)