StrongParametersの使い方


はじめに

本記事では「StrongParametersを使用するとどんな利点があるのか」「基本的な使い方」についてまとめていきます!

StrongParametersの歴史

rails4から導入された機能。
rails3までMassAssignmentを使用していたが、脆弱性の問題があった。

StrongParametersで何ができるのか?

strong parametersを用いることで、Action Controllerのパラメータが許可されるまでActive Modelの「マスアサインメント」に利用されることを禁止できます。つまり、多くの属性を一度に更新したい場合は、どの属性のマスアップデートを許可するかを開発者が明示的に指定しなければなりません。大雑把にすべての属性の更新を一括で許可してしまうと、外部に公開する必要のない属性まで誤って公開してしまう可能性が生じるため、そのような事態を防ぐための機能です。[Railガイド]

・開発者が意図的に必要な属性のみを指定し、取得することができる
・マスアサインメント脆弱性の問題を防ぐことができる。
・意図しない情報の更新や作成を防ぐことができる。

使い方

サンプルコードを使いながらそれぞれのコードについて解説していきます。

ビュー

privateを指定した場合以下のようにモデルを指定する必要がある。
「params.require(:user)..」の場合。

<%= form_with model:@user do |form| %>

コントローラ

[ユーザー情報の取得]

private
 def user_params
   params.require(:user).permit(:name,:email)
 end

private(呼び出し制限)

privateの配下にメソッドを定義することで、クラス外からのアクセスを防ぐことができる。他のクラスではprivate配下のメソッドを使用することができないということ。
※注意点としては、privateはコントローラの最下部に設置すること。配下にあるメソッド全てをアクセス制限してしまうから。
また、protectedという他のインスタンスでも使用できるようにするメソッドもあるが使用頻度は低い。

params.require(キーのオブジェクトを指定)

require(:user)とすることで、特定のオブジェクト(user)を定め、キーを指定して取得することができる。
requireを使用する場合、permitでキーを指定する必要がある。

permit(キーの取得)

permit(:キー)とすることで、そのキーの値を取得することができる。
また、permit!とするとrequireで指定したmodelのキーを全てに権限を与え、取得することも可能。

merge(外部の値を取得)

paramsでは取得していない値を指定することができる。

params.require(:user).permit(:name,:email).merge(user_id: @current_user.id)

[呼び出し方]

def create
 @user = User.new(user_params)
end

User.new(メソッド)とすることでprivateで定義したメソッドの情報を取得することができる。
この場合、user_paramsで指定したキー全てを取得することができる。

まとめ

・ストロングパラメーターを使用することで取得する値を制限することができ、マスアサインメントの脆弱性を防ぐことができる。
・メソッドを定義することで簡単に値を取得することができ、リファクタリングにもなる。

補足(param is missing or the value is empty: user)

requireを使用した時に以下エラーが発生したのでその対処法について。

params.require(:user).permit(:content...)


param is missing or the value is empty: user
エラー内容としては、paramsが存在しないか空の状態であるということ。
結論から言うと、

params.permit(:content,:material,:period)

require(:user)を消しちゃうとエラーは解決できる。
画像でも確認できるようにパラメーターに値は入っているけど、存在しないという内容のエラーになっている。
原因については、以下の記事がわかりやすかった。
param is missing or the value is empty エラー

content: params[:user][:content]...

恐らく、今回の場合だと、上記のようにキーが重複しているため、おきたエラーだと思う。
間違っていたらご指摘いただけると嬉しいです。

追記2021/4/21

params is missing..なのでメソッドの中身をデバックを使用しで把握することでより原因がわかりやすい。

参考資料

Railsガイド
【Ruby on Rails】ストロングパラメータって何なの?
rubyonrails.org
【Rails】param is missing or the value is empty:について