とはいっても仕組みは非常に単純で、ハッシュでパラメータを受け取って、処理結果のオブジェクトを返すだけ。
毎回ファイルを作るのはめんどくさいので、ジェネレータを作る。
まずはコンソールにて
% rails g generator serviceとすると、RAILS_ROOT/lib/generators/service が作成されて、その中には service_generator.rb と templates ディレクトリができる。(あとUSAGEファイル)
まずは、service_generator.rb をいじる。
初期状態がこう。
class ServiceGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)
end
編集結果がこう。class ServiceGenerator < Rails::Generators::NamedBase
# テンプレート検索のパスを追加
source_root File.expand_path('../templates', __FILE__)
# controller のように引数に対応
argument :processes, :type => :array, :default => [], :banner => "process process"
# ファイルを作成する
def create_service_files
template 'service.rb', File.join('app/services', class_path, "#{file_name}_service.rb")
end
end
次に templates ディレクトリに service.rb を作る。class <%= class_name %>Service < ApplicationService
<% for process in processes -%>
def <%= process %>(params = {})
end
<% end -%>
end
まあ、99% controller のジェネレータのぱくりです。これだけで、下記コマンドが実行できます。
% rails g service test foo bar
create app/services/test_service.rb
% rails destroy service test
remove app/services/test_service.rb
ちなみに、service_generator.rb のメソッドですが、定義してあるメソッドを実行するだけみたい。
def hoge puts 'hogehoge' endなんてメソッドを service_generator.rb に追加すると、generate や destroy するたびに実行されて hogehoge が表示されます。
hook_for なんかをつかって spec を同時に生成するようにもしたいけど、ちょっと調べる時間が足りない。
とりあえず hook_for :test_framework はダメでした。