Railsのcontrollerで違和感があるのって
- actionのinputに
params
というインスタンスメソッド経由でアクセスすること(しかもそれはviewからアクセスできる!) - actionのoutputが controller のインスタンス変数への代入であること(しかもそれはviewからアクセスできる!)
というところだと思うんですよ。
なぜなら我々は「メソッドの引数でinputを受け取りメソッドの戻り値をoutputとすべし」ということを是としてコードを書いてるわけじゃないですか。リーダブルコードを読むまでもなく、変数のスコープは狭ければ狭いほどメンテナンスしやすいリーダブルなコードだという知見を正しいものとしてコードを書いているわけじゃないですか。
そういうベストプラクティスに真っ向から反しているのが現在のRailsのcontrollerのあり方なのです。controllerとviewで params
から自由自在にパラメータを引き出して、特定のcontrollerのアクションがどういうパラメータを取りうるかさっぱりわからないということになりがちです。 この params
のスコープの広さはまるでグローバル変数のようです。
ActionArgsは、リクエストパラメータのうち params
でアクセスするパラメータをRubyのメソッドシグネチャで表現できるようにするgemです。
ActionArgsのもとでは、controllerはたとえばこんな感じになります:
class UsersController < ApplicationController def index(page: '1', per: '20') @users = User.page(page).per(per) end def show(id:) @user = User.find(id) end end
#index
が任意パラメータとしてpage
と per
をとり、それらのデフォルト値がそれぞれ1と20であること、show
が必須パラメータとして id
をとるということが、メソッドのシグネチャをみるだけで一目でわかりますね。すばらしい。もっとも、 #create
や #update
の場合はパラメータのデータ構造がネストするのでそれほど自明ではありませんが、それでもないよりはずっとマシです。スコープの広すぎる params
を使わなくて済むのですから。
個人的にはActionArgsがRails組み込みでほしいですが、まずは誰もが使う標準的なgemにならないとなと思ってこのエントリを書きました。