概要
gem action_args の README を翻訳しました。
-
翻訳について
-
ライセンスについて
- action_args のライセンスと同様のライセンスに従います。
action_args
Rails のコントローラーアクションの引数のパラメーター化
これは何?
action_args はコントローラーのアクションメソッドを拡張するプラグインで、任意のアクションのメソッド定義において目的の引数を指定することができるようになります。つまり、この gem は Rails のコントローラーを Merb 流にします。
コントローラー
下記のコードをご覧ください。
class UsersController < ApplicationController
def show(id)
@user = User.find id
end
end
"/users/777" をリクエストしたとき、リクエストは UsersController#show
を呼び出してメソッドパラメーターとして 777 を渡します。
これにより、アクションにおいてもっとも重要な API(params
ハッシュの属性はコントローラーの中で使用される)を完全に自然な Ruby の書き方で宣言することができます。
Ruby のメソッドパラメータータイプと action_args のパラメーターの処理方法
必須パラメーター (:req)
指定したメソッドパラメーターは必須となります。同じ名前のキーが params ハッシュにない場合は、ActionContrller::BadRequest が発生します。
下記の show
アクションでは、id
パラメーターが与えらえることを action_args は要求します。
class UsersController < ApplicationController
# `id` パラメーターは必須
def show(id)
@user = User.find id
end
end
オプショナルパラメーター (:opt)
デフォルトパラメーターは標準的な方法で割り当てられます。デフォルト値を伴うパラメーターは params
ハッシュ内にマッチするアイテムを必要としません。
class UsersController < ApplicationController
# `page` パラメーターはオプショナル
def index(page = nil)
@users = User.page(page).per(50)
end
end
キーワード引数 (:key)
Ruby 2.0 シンタックスのキーワード引数が読みやすい場合は、アクションメソッドの定義にそれを選択することができます。
キーワード引数は :opt
と同じ方法で動作します。
class UsersController < ApplicationController
# `page` パラメーターはオプショナル
def index(page: nil)
@users = User.page(page).per(50)
end
end
必須キーワード引数 (:keyreq)
:keyreq
は :key
が必須となったバージョンです。これは Ruby 2.1 で導入されました。:req
の代わりにこのシンタックスを使うことができます。
class CommentsController < ApplicationController
def create(post_id:, comment:)
post = Post.find post_id
if post.create comment
...
end
end
ストロングパラメーター: permit メソッド
action_args は Rails 4 で導入されたストロングパラメーターと一緒に動作します。
- インラインの宣言
ハッシュはシンプルにストロングパラメーターの permit
メソッドに応答します。
class UsersController < ApplicationController
def create(user)
@user = User.new(user.permit(:name, :age))
...
end
end
- 宣言的な許可リスト
action_args はまたコントローラークラスの宣言的な permits
メソッドも提供します。
これによってわかりやすく permit
の呼び出しを DRY にすることができます。
class UsersController < ApplicationController
# User モデルの属性の許可リスト
permits :name, :age
# 与えられた `user` パラメーターは action_args によって自動的に許可される
def create(user)
@user = User.new(user)
end
end
デフォルトでは、action_args はコントローラー名からターゲットのモデル名を推論します。
たとえば、UsersController
における permits
の呼び出しはモデル名が User
であることを期待します。
このケースに当てはまらない場合は、:model_name
オプションを指定してください。
class MembersController < ApplicationController
# allow-lists User model's attributes
permits :name, :age, model_name: 'User'
end
フィルタ
action_args はコントローラーアクション内で動作するのと同じやり方でフィルタ内でも動作します。
class UsersController < ApplicationController
before_action :set_user, only: :show
def show
end
# params[:id]` は動的にメソッドパラメーターに割り当てられる
private def set_user(id)
@user = User.find(id)
end
end
*_params 規約
Rails のスッキャフォールドのデフォルトの命名規則に慣れている人は、メソッドシグネチャにおいて任意のパラメーターに _params
サフィックスを付けることができます。
それは _params
なしのパラメーター名にマッチします。
たとえば、下記の2つのアクションはメソッドパラメーターとしてどちらも params[:user]
を渡しています。
# without _params
def create(user)
@user = User.new(user)
...
end
# with _params
def create(user_params)
@user = User.new(user_params)
...
end
この命名規則によってコントローラーのコードがより Rails のデフォルト scaffold のコードと一致するようになります。そしてそれによってレガシーな scaffold コントローラーから action_args のスタイルに簡単に手動移行できるようになります。
Scaffold ジェネレーター
action_args はデフォルトの scaffold ジェネレーターを上書きしたカスタム scaffold コントローラージェネレーターを提供します。
なので、下記の scaffold ジェネレーターコマンドを実行すると、
% rails g scaffold user name age:integer email
下記のエレガントなコントローラーコードが生成されます。
class UsersController < ApplicationController
permits :name, :age, :email
# GET /users
def index
@users = User.all
end
# GET /users/1
def show(id)
@user = User.find(id)
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit(id)
@user = User.find(id)
end
# POST /users
def create(user)
@user = User.new(user)
if @user.save
redirect_to @user, notice: 'User was successfully created.'
else
render :new
end
end
# PUT /users/1
def update(id, user)
@user = User.find(id)
if @user.update(user)
redirect_to @user, notice: 'User was successfully updated.'
else
render :edit
end
end
# DELETE /users/1
def destroy(id)
@user = User.find(id)
@user.destroy
redirect_to users_url, notice: 'User was successfully destroyed.'
end
end
下記の点に注目してください。
- グローバルな
params
メソッドへの参照はありません。 - 各アクションで実際の入力値が何かを理解することが簡単です。
- アクションが通常の Ruby メソッドでも
params
メソッドをモックせずにユニットテストコードを書くことができます。
サポートバージョン
-
Ruby 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x, 2.8 (trunk), JRuby, & Rubinius with 2.0+ mode
-
Rails 4.1.x, 4.2.x, 5.0, 5.1, 5.2, 6.0, 6.1 (edge)
Rails 4.0.x を使用する場合は、1.5.4 を使用してください。
インストール
Gemfile に下記の行を追加することで Rails アプリケーションに action_args をバンドルしてください。
gem 'action_args'
注意
Plain Old Action Methods
action_args がロードされていても、もちろん Merb 流のスタイルと既存の Rails スタイルのアクションメソッドのどちらも使用することができます。params
パラメーターは変わらず利用可能です。
これは action_args は既存のコントローラー API を破壊しないことを意味しています。
引数の命名規則
各アクションメソッドのパラメーター名は params
のキー名に一致します。たとえば、下記の美しくネストされた show
アクションは完璧に動作します(これは効果的なクエリの例にはなっていませんがそれはまた別の話です)。
Rails.application.routes.draw do
resources :authors do
resources :books
end
end
class BooksController < ApplicationController
# GET /authors/:author_id/books/:id
def show(author_id, id)
@book = Author.find(author_id).books.find(id)
end
...
end
デフォルトのパラメーター値
もちろん下記のようにアクションパラメーターのデフォルト値を指定することができます。
class BooksController < ApplicationController
def index(author_id = nil, page = 1)
...
end
end
しかし、いくつかの実装上の理由により、page
パラメーターが与えられないときは、page
変数は実際にはデフォルトで nil になります。
完璧な Ruby のお作法の中でデフォルトのパラメーター値を設定するには、代わりに Ruby 2.0 で導入された "キーワード引数" を使用することを推奨します。
class BooksController < ApplicationController
def index(author_id: nil, page: 1)
...
end
end
これにより、誰もが期待するように page
のデフォルト値は1になります。
Copyright
Copyright (c) 2011- Asakusa.rb. See MIT-LICENSE for further details.