はじめに
みなさん、こんにちは torihaziです
今日はもしかしたら車輪の再発明みたいなことをしてしまったかもしれません。
あるの知りませんでした。
jsonapi_serializerを使っていて
rails g serializer user
みたいなことをするときに
できないんじゃね?と思ってしまってあーだこーだしながら作ってみました。
今調べたらあったみたいです。
経緯
rails g serializer hogeみたいにしたらserializersディレクトリ配下に
hoge_serializer.rbみたいなファイルができて欲しかったので
それをコマンドラインからできる術を調べていました。
なにしろめんどくさかったので。
とりあえずrails generate generator hoge
を使うと
lib/generaters/hogeディレクトリ
とか色々作られることがわかりました。
んで、active_model_serializersだとそれがあるけど
jsonapi_serializerだとそれがないから作るしかない、みたいな結論に
その時はなったので今回作りました。
ゴール
今回はrails g serializer hoge/hoge/hoge
としたら
app/serializers/hoge/hogeディレクトリ配下にhoge_serializer.rbができることまでをゴールにします。
手順
rails generate generator serializer
=> lib配下に色々ファイルができる。
lib/generaters/serializerのserializer_generator.rbに下記を追記
class SerializerGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
def create_serializer_file
template 'serializer.erb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
end
def run_rubocop
# ジェネレートしたファイルのパス
generated_file = File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
# コード整形のためにRubocopを実行
system("bundle exec rubocop -a #{generated_file} > /dev/null 2>&1")
end
end
そしてlib/generaters/serializer/templates配下のserializer.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 %>Serializer
include JSONAPI::Serializer
attributes :id
end
<%= "end\n"*module_namespaces.size %>
<% else %>
class <%= file_name.camelize %>Serializer
include JSONAPI::Serializer
attributes :id
end
<% end %>
と記載
使うときは rails g serializer hoge/hoge/hgoe
とかrails g serializer hoge
です。
namespaceつけたいなら前者だし、そうじゃないなら後者みたいな。
そうすれば前者だとこんなのできる
# frozen_string_literal: true
module Hoge
module Hoge
class HogeSerializer
include JSONAPI::Serializer
attributes :id
end
end
end
説明
説明とまではいかないかもしれません。
コード整形はrubocop使ってます。
で標準出力でるとなんかダサいと思ったので全部/dev/nullに流してます。
あとは自信が詰まった箇所を箇条書きで。
- メソッドは上から順に実行される
lib/generaters/serializerのserializer_generator.rbに defで色々メソッド書きましたが 上から実行されます。 -
__dir__
その実行ファイルがあるディレクトリの絶対パス -
templateメソッド
template(templateファイルがあるパス, 出力先のパス)
詳しいこと書いてます
https://railsguides.jp/generators.html
終わりに
まぁ新しく知識増えたのでよしとしましょう。
rails g generatorなんて知りませんでした。