始めまして!
adventカレンダー3日目を担当させていただきます。
DMM WEBCAMPでメンターをしている吉村です!
よろしくお願いします!
はじめに
Rails始めたばかりの頃、データベースがらみが全く理解できず、
よく夜遅くまで、悩まされたことを覚えています。。。
今回はそんなRails初心者の方向けに、
データベースとはなんぞや!といった仕組みから
具体的なコマンドを一挙に説明・紹介していきたいと思います!
Railsのデータベースってどんな構造なの?!
Railsのデータベースは大きく2つのファイルから成り立っています。
マイグレーションファイルと**スキーマファイル(schema.rb)**です。
まずは、マイグレーションとはなんなのかから解説していきたいと思います。
マイグレーションとは
マイグレーションは、データベーススキーマの継続的な変更 (英語) を、統一的かつ簡単に行なうための便利な手法です。
引用:Railsガイド
よくわかりませんよね笑
本来であれば、テーブルを作成するには、SQL文を直接実行して作成する必要があります。
カラムを追加したりする場合も同じです。
対して、マイグレーションを使う場合は、テーブルを新規作成するためのマイグレーションファイルを作成し、実行します。
カラムを追加する際も同じようにマイグレーションファイルを作成します。
マイグレーションのイメージ
マイグレーションを超簡単に図解すると、
このようになります。
家に例えると、マイグレーションファイルは、家をどんな構造にするかを示した設計図のようなものです。
そして、rails db:migrate
と言うコマンドを実行することで、その設計図に従って家が建てられます。なので、schemaに記述されているものが実際に作られたデータベースの形になります。
※実際はschemaに直接データが保存される訳ではないですが、今回は初心者向けの記事になるのでわかりやすいよう家と表現しています。
逆に家を壊すコマンドもあります。それが、rails db:rollback
と言うコマンドです。
これを実行すると家が壊すことができます。
この辺のコマンドの使い方はあとで詳しく説明します!
マイグレーションの利点
一見マイグレーションと言う機能は面倒に見えますが、この機能を使うことで特定のデータベースの文法に依存せずにテーブルへ行なう操作を記述でき、変更を実施したり元に戻すといった作業が簡単に行なえるようになります。
マイグレーションで使えるコマンド
では、マイグレーションの基礎知識がわかったところで、具体的にどんなコマンドがどんな場面で使えるのかを説明していきます。
rails db:migrate
このコマンドは一番基本的なコマンドになります。
先ほど少し書いた通り、このコマンドを実行することで初めてマイグレーションファイルをもとにデータベースが作成されます。
そして、どんな形のデータベースができたかが確認できるファイルがスキーマファイルになります。
皆さんにも馴染みのあるコマンドだと思います。
== 20200818105133 CreateOrderDetails: migrating ===============================
-- create_table(:order_details)
-> 0.0033s
== 20200818105133 CreateOrderDetails: migrated (0.0034s) ======================
== 20200819150420 CreateAddresses: migrating ==================================
-- create_table(:addresses)
-> 0.0066s
== 20200819150420 CreateAddresses: migrated (0.0068s) =========================
実際にコマンドを打ち込んでみるとこんな処理が走るはずです。
create_table
と言う処理が確認できますね。
これでテーブルが正常に作成できたことがわかります。
rails db:migrate:status
とりあえず、データベース関連で困ったときはこのコマンドを打ち込みましょう!
このコマンドは今どのマイグレーションファイルまで、rails db:migrate
が行われているかを確かめるコマンドです。
Status Migration ID Migration Name
--------------------------------------------------
up 20200729160256 Devise create end users
up 20200729160307 Devise create admins
up 20200812043150 Create items
up 20200812045123 Create genres
up 20200817101827 Create cart items
down 20200818103251 Create orders
down 20200818105133 Create order details
実際にコマンドを打ち込むと、このように今あるマイグレーションファイルの一覧が出てきます。
ここで注目したいのが一番左側にあるStatus
の部分です。
ここがupになっていると言うことは、rails db:migrate
がすでに実行されている状態を表します。
ので、**設計図(マイグレーションファイル)をもとに家(schema)**が建っている状態ですね。
反対に、downになっていると言うことは、rails db:migrate
がまだ実行されていない状態を表します。
ので、まだ設計図を作っただけの状態です。
マイグレーションファイルを編集する時は、Statusがdownになってることを確認してから行いましょう。(理由は後述します。)
rails db:rollback
マイグレーションファイルを作成しrails db:migrate
をした後(Statusがup)に、「カラムを追加したい」「テーブルの中身を書き換えたい」と思った時に使えるコマンドです。
カラムを追加したい時は、直接マイグレーションファイルやスキーマファイルを編集すればいいんじゃないかと思うかもしれませんが、ここで注意です!
まず、スキーマファイルはマイグレーションファイルに従って作られるものなので、基本的に直接書き換えることはないです!
次にマイグレーションファイルを編集すると言う方法なのですが、これは可能です!ただし、rails db:migrate
される前(Statusがdown)であることが条件です。
rails db:migrate
をした後(Statusがup)の時にマイグレーションファイルを書き換えても設計図だけ書き換わっただけの状態になり実際のデータベースの形は変わりません!
なので、一度Statusをdownにする必要があります。
それをするためのコマンドがこのrails db:rollback
になります。
== 20200819150420 CreateAddresses: reverting ==================================
-- drop_table(:addresses)
-> 0.0038s
== 20200819150420 CreateAddresses: reverted (0.0053s) =========================
実際にコマンドを打ち込んでみるとこんな処理が走るはずです。
drop_table
と言う処理が確認できますね。
これでテーブルが正常にもとに戻すことができたことがわかります。
この状態になって初めてマイグレーションファイルを書き換えることができます。
さらに、通常rails db:rollback
は一番最近マイグレイションされたファイルを1つだけもとに戻すものなのですが、
rails db:rollback STEP=○
と任意の数字を指定してあげると、一気に2つ以上のファイルをもとに戻してくれたりもします。
※チーム開発をしてる時に、rollbackを使ってマイグレーションファイルを書き換えるとコンフリクトが起こりますので、注意してください。チーム開発の場合はマイグレーションファイルを新たに作成してカラムを追加したり、削除したりしましょう。
参考:マイグレーションファイルの作成、変更、削除まで
rails db:migrate:reset
このコマンドはデータベースを一度全てリセットして、マイグレーションファイルをもとに再度作り直すコマンドです。
似たようなコマンドにrails db:reset
がありますが、これはスキーマファイルをもとにデータベースを作り直すコマンドで、今あるデータベースの形のままデータだけをリセットしたい時に使います。
基本的にはrails db:migrate:reset
を実行してもらえば間違い無いです。
最後に
いかがだったでしょうか。
マイグレーションファイルやらスキーマファイルやら、カタカナや英語がいっぱい出てきて混乱したかと思いますが、少しずつデータベースにも慣れていきましょう。
データベースは直接書き換えるよりかは、コマンドで実行することが多いので、不安になる気持ちもありますが、適切なコマンドを適切なタイミングで使えるようになると、もっと楽しくなると思います!
それでは、失礼します!