読者です 読者をやめる 読者になる 読者になる

コンパイラかく語りき

import { Fun } from 'programming'

文系プログラマーがRailsでロシア語アプリケーションをつくる⑤

どうも!chuckです。

引き続きRailsでロシア語単語帳を作っていきます(`・ω・´)ゞ

 

chuckwebtips.hatenablog.com

 

今回はデータのカラムを追加したり削除しましたのでその辺について。

 

 

カラムの追加

カラムというのはデータベースの列のことです。

今存在するカラムは「単語」「意味」「分類」「難易度」でした。ここに「発音」「品詞」を追加しました!

 

www.rubylife.jp

こちらのサイト様が参考になりました。

 

1, そもそも db/の構造。

f:id:chuck0523:20150718090647p:plain

まだあまり変更を加えていないので、このようになっています。

db/migrate/の中に、rake db:migrateで作成したデータ構造が入っています。そして最終的な構造がdb/schema.rbに書かれています。

 

カラムを追加する以前のschema.rbは以下のとおり

f:id:chuck0523:20150718091103p:plain

1行目のバージョンに注目してください。タイムスタンプ(日付)が7/12になっています。これは最初にデータ構造を作成した日付です。

 

2, railsコマンドでカラムを追加

ターミナルからカラムを追加するためのコマンドを打ちます。

rails generate migration AddDetailsToWords sound:text class:text

 

rails generate migrationは、お決まりのdb構造になんかする時のコマンドです。今回新しく使用したのがAddDetailsTo。その後にテーブル名を書くことで、テーブルに変更を加えます。

今回はtext型のsoundと、text型のclassを追加します。

 

コマンドを発行するとdb/migrateに以下のファイルが追加されます。

f:id:chuck0523:20150718091709p:plain

add_columnとのことで、カラムを追加する命令であることがわかります。

 

3, 変更の実行

さて、カラム追加の命令はできましたが、まだ実際には追加は行われていません。

実際に追加するためには、おなじみのrake db:migrateです

rake db:migrateすると、db/schema.rbが更新されてこのようになります。

f:id:chuck0523:20150718091906p:plain

しっかりカラムが追加されていますね!バージョンのタイムスタンプも最新になっています

 

ターミナルでも確認。rake dbでお使いのDB環境に入ります。

f:id:chuck0523:20150718092015p:plain

きちんと、カラムが追加されていますヽ(=´▽`=)ノ

 

おまけ, マイグレーションのバージョン確認

rake db:versionで現在使っているマイグレーションのバージョンを確認することができます。

f:id:chuck0523:20150718093020p:plain

 

追加するカラムの順序を変える

ただ、soundやclassが一番最後に来てるのがちょっと落ち着かないです…。単語にとって大切な情報なので、もっと前に置きたい。

そこで見つけたのがこちらのページ。

qiita.com

 

このようにadd_columnのにオプションとしてafterをつけてあげれば良いみたいです。 

f:id:chuck0523:20150718093033p:plain

 

再びrake db:migrate。

すると、

 

f:id:chuck0523:20150718093126p:plain

変わってねーじぇねーか!(# ゚Д゚)

 

ひょっとして、エディタで書き換えても意味ない??また新しくAddDetailToコマンドする必要がある???

というわけで、また別のAddDetailToコマンドを発行。

f:id:chuck0523:20150718093610p:plain

衝突。もうファイルが存在するとのこと。AddDetailToファイルは1コしか作れないのかな。

 

もう一度エディタ側でテスト。testというカラムを追加させる。

f:id:chuck0523:20150718093859p:plain

 

rake db:migrateするも、

f:id:chuck0523:20150718093914p:plain

変わっていない…。

 

migrationを消してみる

f:id:chuck0523:20150718094058p:plain

1コしか作れないとのことなので、1度消してみます。

コマンドはrails destroy migration (ファイル名)

 

f:id:chuck0523:20150718095000p:plain

古いAddDetailsToWordsが消えたのを確認して、もっかいgenerate。

 

コマンドの段階でafterをつけたらどうなるんだろう???

f:id:chuck0523:20150718095039p:plain

 

f:id:chuck0523:20150718095103p:plain

キメラが生まれた。

 

削除削除♪

f:id:chuck0523:20150718095134p:plain

 

今度はafterをつけずにgenerate。

f:id:chuck0523:20150718095157p:plain

 

ここにエディタでafterを追加。

f:id:chuck0523:20150718095233p:plain

 

期待に胸を膨らませつつrake db:migrate。

 

f:id:chuck0523:20150718095259p:plain

エラーーーーーー!!!!(´Д⊂ヽ

 

ひょっとしてDBから根こそぎ消す?

あれですかね。destroy migrationで消したのはファイルだけ??DB構造から直接カラムを消す必要がある??

rake dbで確認。

f:id:chuck0523:20150718095624p:plain

うわあああ、ふつうに残ってんじゃん…

 

カラムの削除

ということで、予定にはなかったんですがカラムの削除もやっていきます。

AddDetailToの反対はRemoveDetailFromらしいです。

rails generate migration RemoveDetailsFromWords sound:text class:text というコマンドを発行。

f:id:chuck0523:20150718100107p:plain

 

誕生したファイル。

f:id:chuck0523:20150718100140p:plain

 

あれ、でも今ってAddDetailとRemoveDetaiのファイルが共存してる。ここでrake db:migrateするとどうなるんだろう…???

 

f:id:chuck0523:20150718100250p:plain

先ほどと同じく重複してるとのこと。

 

いったんAddDetailを隠そう。

f:id:chuck0523:20150718100337p:plain

コメントアウト

 

f:id:chuck0523:20150718100425p:plain

きたー!!カラム消せた!これでafterをつけたカラム追加できるはず!

 

f:id:chuck0523:20150718100516p:plain

コメントアウトを外す。

 

あれ、でも今ってAddDetailとRemoveDetailが共存している…(デジャブ感)

ひょっとしたら特定のmigrationファイルだけを実行。みたいなコマンドあるんじゃない??(ΦωΦ)

 

でもまずはふつうにrake db:migrateしてみる。結果、何も変わらず笑 カラムが作られた瞬間、消されたから???

検証のために、Addにカラムを1つ追加。

f:id:chuck0523:20150718101004p:plain

 

一方、Remove。

f:id:chuck0523:20150718101016p:plain

これならばtestカラムは生き残るはず。

 

f:id:chuck0523:20150718101111p:plain

変わってねー

 

Removeをコメントアウトしてみる。

f:id:chuck0523:20150718101226p:plain

 

addされず。あれ、さっきaddをコメントアウトしたらremoveできたよね??なんで逆はできないの???(# ゚Д゚)

 

特定のmigrationファイルを実行する

調べたらあった。

qiita.com

コンソールから実行するらしい。

f:id:chuck0523:20150718101818p:plain

できた!

 

f:id:chuck0523:20150718101838p:plain

でもデータ構造変わってないんですが。

 

そもそもrake db:migrateって何

そもそも論。rake db:migrateの理解が間違っているんじゃないかという考えに行き着く。

rake db:migrate - リファレンス - - Railsドキュメント

 

f:id:chuck0523:20150718102342p:plain

ん???

未実行のマイグレーションファイルの実行???

 

そうなの?じゃあ一度実行されたファイルはもう実行されないの??

でもたしかに最初に作ったcreate_tableのファイルとか実行されてないよね。たぶん。いちいちコンソールに「テーブル作りました」みたいに出ないもんね。

 

f:id:chuck0523:20150718102613p:plain

これをやってみる。

 

f:id:chuck0523:20150718102628p:plain

反応なし。そっか、みんな実行されちゃったんだ。

 

ためしに新しくmigrationファイルを作成。

f:id:chuck0523:20150718102755p:plain

 

もっかい未実行のマイグレーションファイル調べる。

f:id:chuck0523:20150718102812p:plain

反応した。

 

せっかくだからafterをつけて実行してみる。

f:id:chuck0523:20150718103045p:plain

 

f:id:chuck0523:20150718103053p:plain

まあ未実行だし通る。

 

f:id:chuck0523:20150718103106p:plain

なるほど。afterは効いてないけど、追加はされた。

 

さっき起こったこと。

コメントアウトしたAddファイルは、空の状態で実行されちゃったんだ。で、使用済みになってしまったのか。

空のAddと空でないRemoveが同時に実行されて終わってしまった模様。なるほど(ヽ´ω`)

 

ここでresetの存在を思い出す

そういえばrake db:resetとか言う便利なコマンドあったよね(今更) 

f:id:chuck0523:20150718103811p:plain

 

不要なマイグレーションファイルを削除して、やってみる。

f:id:chuck0523:20150718103948p:plain

 

あ、ちょっと待って。なんか僕の知ってるコマンドと違う。

調べた。

easyramble.com

そうそう!これが知りたかった!

 

rake db:resetはdb/schemaを参考に、

rake db:migrate:resetはdb/migration/ を参考に、

テーブルを作り直すらしい。

後者の場合は古いバージョンのファイルから読み込まれるとか。

 

これけっこう大きな違いじゃない??

 

ちなみに、ファイル構造ふたたび。

f:id:chuck0523:20150718095000p:plain

 

リセット

まずは、rake db:resetでテーブルを初期状態に戻します。

f:id:chuck0523:20150718105204p:plain

参考にされるdb/schema.rb。

 

f:id:chuck0523:20150718105245p:plain

リセットされたテーブル。

 

次にrake db:migrate:resetでAddを実現。

f:id:chuck0523:20150718105343p:plain

Addファイル。

 

f:id:chuck0523:20150718105357p:plain

ちなみに、Removeは空にしました。

 

すると、見事に理想通りのカラム作成が行われました…!

f:id:chuck0523:20150718105108p:plain

 

f:id:chuck0523:20150718105451p:plain

きちんと2つのカラムが追加されていることが分かる。

 

しかし、やはりafterが効いていない… これは次回までの宿題としますヽ(´Д`;)ノアゥア…

 

あと、当然ですがテーブルをリセットすると中のデータは消えるので要注意!

f:id:chuck0523:20150718105644p:plain