よく忘れるので。細かい話は他の記事にお任せして、テンプレートからファイルを作れるところまで。
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以外も使えるかもしれない