LoginSignup
2
2

More than 3 years have passed since last update.

gem action_args の README を翻訳しました

Last updated at Posted at 2020-05-03

概要

gem action_argsREADME を翻訳しました。

  • 翻訳について

    • 翻訳サービス DeeplGoole翻訳 の訳文を参考にしている箇所があります。
    • 翻訳対象のコミットハッシュ
    • 非公式の翻訳です。
    • 訳文がおかしい箇所があったら指摘をもらえると幸いです。
  • ライセンスについて

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.

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2