Railsで開発している際、コントローラー内で render_xxx のような独自メソッドをよく見かけます。特に API を構築する際に、render_api や render_json などのレスポンス構成を共通化するために、render json:
の処理をラップしたコードをよく目にします。
以下のようなコードです。実際には内部で別のプライベートメソッドを呼び出すなど、複雑な実装が含まれていることもあります。
# api を返すときはこのメソッドを使う ← よく見るコメント def render_api(object, status: 200) render json: { data: object, status: status } end # 利用部分 render_api(record, status: 200) # json レスポンス # {"data":{"id":1,"created_at":xxx,"updated_at":xxx,"name":"john"},"status":200}
しかしこのアプローチには何か違和感があります。特には複数のプライベートも重ねて実行されることもあり、無駄に application_controller のようなベースコントローラにつらつらと書かれていることも多く、見てて気持ちいい実装ではありませんでした。
常に同じ形式で使用するのであれば、render api: xxx
のようなシンタックスがよりスマートであると感じるのではと。
ActionController::Renderers.add による改善
この違和感を解消するための方法として、 ActionController::Renderers.add
で renderer を追加するやり方があります。
これを導入することで、render hoge: xxx
のような記述でレスポンスを返すことができるようになります。
# config/initializers/add_controller_renderer.rb ActionController::Renderers.add :api do |object, options| json_response = { data: object, status: options[:status] || 200 } render json: json_response, status: json_response[:status] end
上記のコードを追加するだけで、以下のようにレスポンスを生成できます。
# コントローラ内で下記のように利用可能 render api: record, status: 200 # json レスポンス # {"data":{"id":1,"created_at":xxx,"updated_at":xxx,"name":"john"},"status":200}
個人的にはこっちの方がより Rails チックでスマートな記述に感じます。 このアプローチを取ることで、独自のレンダリングメソッドをコントラーラ内部につらつらと追加する必要もなくなります。
api のレスポンスの他にも react 描画用の html などのテンプレ形式で返す際にも便利なのでおすすめです。