💎
rubyで個人的に綺麗だと感じるcontrollerを実装できるgemをリリースしてみた
gem概要
1コントローラー1アクションに整理した実装をできるgemを作りました。
(rails wayに沿っているかは気にしていない。)
依存関係はできるだけ少なくしてます。
コントローラー
execute
ブロック以外は任意実装です。
before
, after
hookや、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