はじめに
みなさん、こんにちは torihaziです
今日は昨日初めて知ったRailsの自作ジェネレータを実際に使ってみたということで練習がてら作ってみました
昨日の時点で便利では?と思ったので今後も使っていきたいと思います
ちなみにalbaはこれです。Railsのシリアライザ?です。
https://github.com/okuramasafumi/alba
経緯
今作っているXクローン用に昨日ずっとRailsのSerializerを探していて、jsonapi-serializerとか色々触ってみたのですがどれも「うーん」ということで辿り着いたのが albaでした。
その時の体験記がこれです。
https://torihazi.hateblo.jp/entry/2024/10/25/220337
このついでに毎回ファイル手動で作るのだるいとなってrails g serializer
があることを知り、さらにこの"ジェネレータ"自体が自分でも作れるのを知りました。
で、albaが見てみた感じなさそうだったのでその時得た知識をもとに作ってみよう!となって今に至ります。
その前に
導入方法とかはこの方のものを参考にしてください
https://zenn.dev/hujuu/articles/implement-alba-in-rails
どういうものか
結論言うと、
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に投げてください
https://railsguides.jp/generators.html
ポイントをかいつまんで説明すると
- 上から下へ順に 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の記述あれな場合は、上手い具合に改造しちゃってください
ということで。