よく忘れるので。細かい話は他の記事にお任せして、テンプレートからファイルを作れるところまで。
0. こんなのを作りたいとかんがえる
- 抽象クラス
Figure
のサブクラスをapp/models
に作るようなジェネレータがほしい。 - クラス名は引数で指定したい
こんな感じで使うイメージ:
$ rails g figure triangle --color blue
1. ジェネレータをジェネレートする
$ rails g generator figure
これでlib/generators/figure
以下に
- USAGE : 使い方を記述するテキストファイル
- figure_generator.rb : 生成処理を実装するファイル
- templates/ : テンプレートファイルを置くディレクトリ
が作られる。
2. 作り方を記述する
USAGEファイルに0.のようなことを記述する。
3. 生成処理を記述する
lib/generators/figure/figure_generator.rb に次のように記述する。
class FigureGenerator < Rails::Generators::NamedBase source_root File.expand_path('../templates', __FILE__) # 引数として受け取る順番に記述する # ここで宣言した引数名はそのままその値を返すメソッドとしても使える # 追記: NamedBaseの場合はデフォルトでnameが宣言されているのでここではなにもしない # argument :name, type: :string, desc: "クラス名。underscoreな形でもOK" # オプションを記述する # ここで宣言したオプションは`options[:color]`のように参照できる class_option :color, type: :string, aliases: "-c", desc: "色" # 以下に宣言されたpublicなメソッドが上から順に実行される def create_model_file # テンプレートをもとにapp/modelsにファイルを作る template "model.rb.erb", "app/models/#{name.underscore}.rb" end private # このクラス上のメソッドはテンプレートからも呼び出せるので # 積極的にprivateメソッドで宣言していきたい def class_name name.classify end end
4. テンプレートファイルを記述する
figure_generator.rb でtemplate
メソッドの引数に渡した model.rb.erb にテンプレートを記述する。ファイル名のとおりERBを使う。 *1
class <%= class_name %> < Figure def apexes_count # 頂点の数を返す end def color "<%= options[:color] %>" end
5. 使ってみる
$ rails g figure triangle --color yellow
9/17 追記
class_option
によるオプションの宣言方法を追記した。
ちなみにargument
やclass_option
はThor::Base::ClassMethodsで定義されているもの。
10/3 追記
NamedBaseの場合はすでにname
がargument
で宣言されており別途宣言する必要がないので、ここではコメントアウトした。
*1:もしかしたらファイル名を適切に設定すればERB以外も使えるかもしれない