alba用の"rails g alba hoge"みたいなジェネレータを作った
はじめに
みなさん、こんにちは torihaziです
今日は昨日初めて知ったRailsの自作ジェネレータを実際に使ってみたということで練習がてら作ってみました
昨日の時点で便利では?と思ったので今後も使っていきたいと思います
ちなみにalbaはこれです。Railsのシリアライザ?です。
経緯
今作っているXクローン用に昨日ずっとRailsのSerializerを探していて、jsonapi-serializerとか色々触ってみたのですがどれも「うーん」ということで辿り着いたのが albaでした。
その時の体験記がこれです。
このついでに毎回ファイル手動で作るのだるいとなってrails g serializer
があることを知り、さらにこの"ジェネレータ"自体が自分でも作れるのを知りました。
で、albaが見てみた感じなさそうだったのでその時得た知識をもとに作ってみよう!となって今に至ります。
その前に
導入方法とかはこの方のものを参考にしてください
どういうものか
結論言うと、
rails g alba tweetWithImages --model tweet
とするとapp/resources配下にファイルが出来ます。
なければ作成されます
# frozen_string_literal: true
class TweetsWithImagesResource < BaseResouce
root_key :tweet
attributes :id
end
class BaseResource
include Alba::Resource
end
ちなみにnamespace作って云々したければ
rails g alba hoge/hoge --model hoge
とすればapp/resources/hoge
配下にファイルが出来ます。
なければ作成されます。
# frozen_string_literal: true
module Hoge
class HogeResource < BaseResouce
root_key :hoge
attributes :id
end
end
こっちもbase_resource.rbがなければできます。
とこんな感じ。
いざ
ジェネレータ作ります。
rails g generator alba
結果、lib/generators/alba
配下に色々ファイルやらディレクトリができます。
まず触るのはalba_generator.rb
class AlbaGenerator < Rails::Generators::NamedBase
source_root File.expand_path('templates', __dir__)
class_option :model, type: :string, default: 'sample'
def create_alba_base_file
base_resource_path = File.join('app/resources', 'base_resource.rb')
unless File.exist?(base_resource_path)
create_file base_resource_path, <<~RUBY
class BaseResource
include Alba::Resource
end
RUBY
end
end
def create_alba_file
template 'alba_template.erb', File.join('app/resources', class_path, "#{file_name}_resource.rb")
end
def run_rubocop
generated_file_path = File.join('app/resources', class_path, "#{file_name}_resource.rb")
system("bundle exec rubocop -a #{generated_file_path}", out: File::NULL, err: File::NULL)
end
private
def model
options['model']
end
end
下記を見れば大体書いているので参考にしてください。なければAiに投げてください
ポイントをかいつまんで説明すると
- 上から下へ順に def で定義したパブリックなメソッドが実行されます
- class_optionはコマンドの引数を追加したい場合設定します
- class_optionで定義した引数はoptions['引数名']で取得します
- templateメソッドは テンプレートファイルを第1引数に、それを元に作るファイルのパスを第2引数にとります
- コード整形用にrubocop使ってます
くらいです。頭のいいみなさんなら秒なので多分平気です。
次にtemplates/alba_template.erb
を作成し、記述します。
# frozen_string_literal: true
<% module_namespaces = class_path.map(&:camelize)%>
<% if module_namespaces.any? %>
<%= module_namespaces.map{|namespace| "module #{namespace}"}.join("\n") %>
class <%= file_name.camelize %>Resource < BaseResouce
root_key :<%= model %>
attributes :id
end
<%= "end\n"*module_namespaces.size%>
<% else %>
class <%= file_name.camelize%>Resource < BaseResouce
root_key :<%= model %>
attributes :id
end
<% end %>
てすれば、もうあとは rails g alba ファイル名 --model 対象のmodel
を実行すればいけます。
終わりに
rubyの記述あれな場合は、上手い具合に改造しちゃってください
ということで。
Discussion