リクエストパラメータの検証を行うStrongParameter(ストロングパラメータ)
Railsで開発を行なっているとActiveModel::ForbiddenAttributesErrorというのに遭遇するのですが、このエラーを解決するにはRailsのStrongParameter(ストロングパラメータ)という仕組みを理解しておく必要があります。
StrongParameter(ストロングパラメータ)とは?
StrongPrameterとは、Railsでリクエストパラメータを検証するための仕組みです。
シンプルなCRUDを開発する場合に、フォームから送信された値を元にインスタンスを生成して、レコードを作成ということを行うと思いますが、パラメータの中にはクライアント側(ユーザ)が変更できて良い値と変更できてはいけない値があります。
例えば、ブログを投稿するフォームを考えると公開日時や更新日時をユーザからのリクエストに基づいて設定できるというよりは、サーバ側でのレコード作成・更新の時間を記録するという場合が考えられます。
この例のようにクライアント側にどういったパラメータでのモデルの作成・更新を許可するか?というのを設定するのがストロングパラメータです。このストロングパラメータを介さずにモデルを作成・更新を行おうとすると冒頭で説明したActiveModel::ForbiddenAttributesErrorが発生します。
StrongParameterの使い方
ストロングパラメータは下記例のblog_paramsメソッドの様に使用します。
class BlogsController < ApplicationController
before_action :blog_params, only: [:create, :update]
def new
@blog = Blog.new
end
def create
blog = Blog.new(blog_params)
if blog.save
redirect_to :index, notice: '投稿しました'
else
flash.now[:alert] = blog.errors.first
render :new
end
end
def update
blog = Blog.find(params[:id])
if blog.update(blog_params)
redirect_to :index, notice: '更新しました'
else
flash.now[:alert] = blog.errors.first
render :new
end
end
private
def blog_params
params.require(:blog).permit(:title, :content, :category)
end
end
requireメソッドは、必須のリクエストパラメータを指定することができ、もし指定した(:blog)パラメータがない場合は不正なリクエストとしてレスポンスが返却されます。 permitメソッドは、ホワイトリストとして許可されたパラメータを指定して引数に渡すことでパラメータがそのままモデルの作成・更新に使われることを許可します。
以上のことから上記の例で許可されるパラメータは下記のような形になります。
{
blog: {
title: 'title',
content: 'content',
category: 1
}
}
現状の実装ではこれ以外のパラメータが渡されても許可されたキー以外のパラメータは無視されます。もしblogというパラメータだけあればあとはその中身全てを許可するという場合はpermit!メソッドが使えます。
private
def blog_params
params.require(:blog).permit!
end
このように書くことでblog配下のキーは全て許可されます。permit!メソッドは開発で暫定的に使用するのは良いですが、基本的にはpermit!を使わずにひとつずつちゃんとリスト化して許可する のが望ましいです。
まとめ
Railsで最初にCRUDを開発しているときによくぶつかるのが冒頭で紹介したActiveModel::ForbiddenAttributesErrorです。このエラーを検索してみるとそれに関する記事がいくつかできるのでそれで解決することはできるのですが、初心者のうちだとなんとなくその記事のコピペで終わってしまうのでちゃんとストロングパラメータを使う意味も理解できるとよいですね。
この記事を読み終わったらこちらのRailsガイドも読んでおくと良いかと思います。 https://railsguides.jp/actioncontrolleroverview.html#strong-parameters