2.0のscaffoldで上書きする
一度scaffoldを実行した後、同じモデルに何らかの変更をして再度scaffoldを実行したい場合、最初と同じ手順では実行できなかった...。
マイグレーションファイルの取り扱い
- 2度目のscaffoldを実行したとき、同じモデルで既にマイグレーションファイルが存在すると、メッセージの最終行に以下のように表示され、何も更新されない。
Another migration is already named create_slips: db/migrate/001_create_slips.rb
2度目のscaffoldでファイルを上書きするためには...
- オプション--skip-migrationを指定する。(マイグレーションファイルの生成をスキップする。)
- →マイグレーションファイルは自分で修正、またはバージョンを追加する。
- 既に存在するマイグレーションファイルを削除してしまう。
ここで、Railsはどうやって同じモデルのマイグレーションだと理解するのか、という疑問が浮かぶ。
- 試しにファイル名を001_create_slips.rb → 001_create_slips1.rbのように変更してみると...
マイグレーションファイル名を変更する時の注意
マイグレーションファイル名とその中身のマイグレーションクラス名は連動しているので、ファイル名を「001_create_slips1.rb」のように変更したら、クラス名も「CreateSlips1」のように変更する必要がある。この変更をしないとマイグレーションを実行した時にエラーが発生する。
rake aborted! uninitialized constant CreateSlips1
scaffoldでマイグレーションファイルが生成されるようになったので、矛盾を防ぐためにこのような仕様になっていると思う。もし、マイグレーションファイルが上書きされてしまうと、データベースの状態とマイグレーションファイルに不整合が発生してしまい、後で困った状況になってしまうからだろう。
上書きの選択
- scaffoldでファイルの上書きが発生する場合、以下のようなメッセージが表示される。
overwrite app/controllers/slips_controller.rb? (enter "h" for help) [Ynaqdh]
- 改行、まはたhを指定すると、選択肢のペルプが表示される。
Y - yes, overwrite(上書きする) n - no, do not overwrite(上書きしない) a - all, overwrite this and all others(すべてのファイルで上書きする) q - quit, abort(scaffold処理を中断する) d - diff, show the differences between the old and the new(新旧の差分を表示する) h - help, show this help(ヘルプ表示)
- 初めて見るdオプションは素晴らしかった!既存ファイルと新規生成されるファイルのdiffを実行してくれる。(差分を表示する)
--- /Users/zari/railsapp/test202/app/controllers/slips_controller.rb +++ /Users/zari/railsapp/test202/app/controllers/slips_controller.rb.26440.0 @@ -4,6 +4,10 @@ def index @slips = Slip.find(:all) + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @slips } + end end # GET /slips/1 retrying overwrite app/controllers/slips_controller.rb? (enter "h" for help) [Ynaqdh]
- 変更内容を確認してから、上書きするか、しないかを選択すれば良いのだ。
ルートファイルの取り扱い
- 正常にscaffoldが実行される度に、config/Routes.rbにmap.resources :slipsが追加されていく。油断していると、以下のような状態に...。
ActionController::Routing::Routes.draw do |map| map.resources :slips map.resources :slips map.resources :slips ...(中略)...
- 重複する行は不要なので、削除しておいた。
*1:create_モデル名sというマイグレションファイルの存在をチェックしていると推測