前置き
Railsには、DBのマイグレーションファイルを作成する為のジェネレータ、rails g migration
があります。 例えば、users
テーブルにemail
カラムを追加したい場合、このジェネレータは以下のように使います。
$ bin/rails g migration AddEmailToUsers email:string invoke active_record create db/migrate/20160501030424_add_email_to_users.rb
そうすると、db/migrate/20160501030424_add_email_to_users.rb
が生成されます
class AddEmailToUsers < ActiveRecord::Migration def change add_column :users, :email, :string end end
問題点
私は、このコマンドにいくつかの問題があると思います。
- カラム名を2回書かなければいけない
- クラス名のルールを覚えなければいけない
以下で詳しく説明します。
カラム名を2回書かなければいけない
AddEmailToUsers
と email:string
の2箇所にemail
と書かなければいけません。
同じことを2箇所に書かなければいけないのはイケてないですね。
クラス名のルールを覚えなければいけない
rails g migration
は、クラス名をパースしてどのようなマイグレーションファイルを生成するか決定します。
そのため、どのようなクラス名をつけたらどのようなファイルが生成されるかを覚えなければいけません。
また、「クラス名からアクションが決定される」というのは直感的でないと私は考えます。
「アクションを記述するとクラス名が決定される」というアプローチの方が、より自然ではないでしょうか?
解決策
以上のような問題を感じたため、rails g migration
の代替となるgem、mi
を作成しました。
インストール
Gemfile
に以下のように追記して、bundle install
するだけです。
gem 'mi'
使い方
このGemをインストールするとmi
というジェネレータが追加されます。
先ほどと同じようにusers
テーブルにemail
カラムを追加したい場合は、以下のようなコマンドを実行します。
$ bin/rails g mi users +email:string
create db/migrate/20160429062420_add_email_to_users.rb
すると、db/migrate/20160429062420_add_email_to_users.rb
が以下のように生成されます。
class AddEmailToUsers < ActiveRecord::Migration def change add_column :users, :email, :string end end
生成されたファイルの中身は従来のrails g migration
と同一ですが、カラムの指定方法などが異なります。
mi
では、「テーブル名」と「カラム名(と型)」を指定してマイグレーションファイルを生成します。
従来のジェネレータとは違いクラス名を指定する必要はなく、自動生成されます。
解説
$ bin/rails g mi users +email:string
上記のコマンドを詳しく解説していきましょう。
まず、users
はテーブル名を表します。
+email:string
は、+
, email
, string
の要素に分けられます。
+
は、add_column
を表します。ここを-
や%
に変えると、それぞれremove_column
やchange_column
を表します。
$ bin/rails g mi users -email # => remove_column :users, :email $ bin/rails g mi users %email:text # => change_column :users, :email, :text
email
, string
はそれぞれカラム名と型名を表します。
remove_column
の例からわかるように、型名は省略可能です。
また、以下のようにしてオプションを渡すことが可能です。
$ bin/rails g mi users +email:string:{null:false} # => change_column :users, :email, :string, null: false
TODOs
現在、まだまだ 実装されている機能は多くありません。
create_talbe
ができないrename_table
,change_column_null
などに対応していない- Rails 5に対応していない
以上の様なTODOが残っています。が、早いうちに実装しようと思っています!
ちなみに、Rails 5でmigrationファイルの形が変わるっぽいですね。
Rails 5から導入されたmigration versioingについて | 日々雑記
まとめ
カラムの追加など、よくあるマイグレーションファイルの生成を簡単かつ直感的なシンタックスで行えるGem、mi
の紹介でした。
まだ全てのマイグレーションを置き換えることは出来ませんが、確実にマイグレーションファイルの生成を効率化することが出来ると思います。
rails g migration
にフラストレーションを感じたことのある方は是非一度お試しください!