Torihaji's Growth Diary

Little by little, no hurry.

rails g serializer の再発明。(jsonapi_serializerでも使えることを知らなかった)

はじめに

みなさん、こんにちは 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なんて知りませんでした。