💎

rubyで個人的に綺麗だと感じるcontrollerを実装できるgemをリリースしてみた

2024/10/29に公開

gem概要

1コントローラー1アクションに整理した実装をできるgemを作りました。
(rails wayに沿っているかは気にしていない。)

依存関係はできるだけ少なくしてます。

https://rubygems.org/gems/dear-dirty-controller

https://github.com/youtaman/dear-dirty-controller

コントローラー

executeブロック以外は任意実装です。
before, afterhookや、serializerなどあったら便利そうなメソッドもついでに実装しています。
興味がある方はgithubのreadmeを覗いてみていただけると嬉しいです。

class GetUserController
  include DearDirtyController::Mixin
  attr_reader :request

  serializer UserSerializer

  before do
    @context.started_at = Time.new
    Rails.logger.info "[START] get user"
  end

  execute do
    @request = ActionDispatch::Request.new(args)
    User.find(params[:id])
  end

  after do
    @context.ended_at = Time.new
    sec = @context.ended_at - @context.started_at
    Rails.logger.info "[END] get user (#{ sec } sec)"
  end

  def params
    ActionController::Parameters.new(request.params)
  end
end

routes.rb

pathとコントローラーが対になることを目指しました。
エディタのコードジャンプも使えるし、pathから逆引きでcontrollerを探すことが簡単になっていると思います。
resource, resourcesなどは使えないです。

  scope :api do
    get "/users/:id", to: GetUserController
  end

何故作ろうと思ったか

  • gemを作ってみたかった
  • routes.rbで結局どのcontrollerのどの関数を読みにいけば良いのかがぱっと見分かりづらいと思ってた
    scopeとかmoduleとかnamespaceとかを使っていると複数行読まないとcontrollerは特定できない。
  • アクションとアクションが利用する関数・定数が離れているcontrollerが読みづらいから
    class XxxController < ApplicationController
      # index_params, index_serializerの実装箇所が物理的に離れていて読みづらい
      # エンドポイントとして公開するものだけpublicな関数にした方がいいのでしょうがない。。。
      def index
        # do something
        index_serializer.serialize
      end
    
      def show
        # do something
      end
    
      private
    
      def index_params
        # do something
      end
    
      # 以下略 show_params, index_serializer, show_serializerなどが実装されている
    end
    

今後の予定

これ以上のアップデートは特にするつもりはないです。
ただ、railsに依存した以下の機能が欲しいので、新規でrails用のgemを作成しようと思ってます。

  • routes.rbでresource, resourcesを使えるようにする
  • ActionDispatch::Routingが渡してくれる引数の処理をgem側で実装
  • パラメータのバリデーション機能

感想

gemの開発を通してrubyの知識が深まったなと思ってます。
今までは利用しているgemのソースコードを読むときも雰囲気で読んでましたが、今後は仕組みがわかっているので楽に読めそうです。
このgemのようにrailsに依存しておらず、純粋なmoduleやPOROだけを提供するgemであれば簡単に作れるので勉強のために作ってみるのもオススメです。

Discussion