すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Rails

【Rails】 ストロングパラメータの仕組みを理解しよう!

ぴっかちゃん
ぴっかちゃん

ストロングパラメータとは、フォームから入力された情報を指定して、安全に受け取るための仕組みです。設定しておくことにより不正な情報を受け取ることを防ぎます。

ストロングパラメータの使用例
1
2
3
def tweet_params
  params.permit(:title, :text)
end

ストロングパラメータの使い方

この章では、ストロングパラメータの使い方について解説します。

なぜ使う必要があるのか

投稿フォームに入力された情報はparamsによって取得できます。
その際、不正に投稿された内容がparamsに含まれているとその情報まで保存されてしまいます。

そこでストロングパラメータというものを設定しておきます。
ストロングパラメータを設定しておくと指定したカラムの情報だけを受け取ることができます。

ストロングパラメータの定義の仕方

以下のようなコードがストロングパラメータです。

コントローラー -->
1
2
3
def tweet_params
  params.permit(:title, :text)
end

この中で使っているpermitメソッドはparamsで取得したキーのうち、データベースに保存してもいいものを許可するメソッドです。
permitメソッドについてはpermitメソッドを使ってストロングパラメータにしようの記事を参照ください。

上の例ではtitleカラムとtextカラムの値だけデータベースに保存されることを許可しています。
ですので、たとえparamsの中に他のカラムのパラメーターがあってもデータベースには保存されません。
このtweet_paramsの返り値は{ title: "入力した値, text: "入力した値" }となります。

設定する理由

createアクションの引数に下記のようにparamsとするとエラーが出て保存できません。

コントローラー -->
1
Hoge.create(params)

これはもし不正なパラメーターが入っていた場合、それまで取り出してデータベースに保存されるのを防ぐためです。
どのような仕組みでエラーが出るのでしょうか?それを確認してみましょう。

binding.pryで処理を止めてparamsでパラメーターを取得すると下記のようなコードになっています。

コンソール -->
1
2
3
4
5
6
7
8
[1] pry(#<UsersController>)> params
=> <ActionController::Parameters 
{"utf8"=>"✓", 
"authenticity_token"=>"hogehoge==",
 "name"=>"プログラマン2号",
 "job_id"=>2,
 "controller"=>"users",
 "action"=>"create"} permitted: false>

最後の行を見るとpermitted: falseというコードがあります。
この状態でcreateアクションの引数にparamsを指定するとエラーが出てしまうというわけです。

では次にストロングパラメータ内に書いたpermitメソッドを使った返り値を確認してみましょう。

コンソール -->
1
2
3
4
pry(#<UsersController>)> params.permit(:name,:job_id)
Unpermitted parameters: :utf8, :authenticity_token
=> <ActionController::Parameters
 {"name"=>"プログラマン2号", "job_id"=>2} permitted: true>

最後の行がpermitted: trueになっているのが確認できますね。
そしてpermitで指定していないparamsで取得した他のパラメータはUnpermitted parametersとなっています。
このようにストロングパラメータを定義するとエラーなく保存ができるというわけです。

ストロングパラメータはclass内でprivateメソッドを使い定義します。

privateメソッド

クラスを定義するときにprivateメソッドを呼び出すとそれ以降に定義されるインスタンスメソッドはそのクラス中でしか呼び出されなくなります。
privateメソッドを使っておけばクラス外部で呼び出されるとエラーが起きるようなメソッドが使われるのを防ぐことができたり、コードの可読性が上がるなどのメリットがあります。

ストロングパラメータはクラス内部でしか使わないので、そういうメソッドはprivate以下に定義しておきましょう。こちらのRuby on Railsの良書として有名な書籍でも触れられているのでぜひ参考にしてみてください。

実際のアプリでストロングパラメータを定義してみよう

下記のコマンドを順に実行してみましょう。

ターミナル | ①リポジトリを複製
1
git clone -b strong_parameters https://github.com/miyagit/programan_dojo.git
ターミナル | ②programan_dojoのディレクトリに移動
1
cd programan_dojo
ターミナル | ③bundle installを実行
1
bundle install 

rbenv: version ‘2.4.1’ is not installedと表示された場合は、ruby -vと実行してください。

もしruby -vと実行し出てきたversion(例: 2.3.1)と出てきたら、vim .ruby-versionとしてruby -vで出てきた値(例: 2.3.1)に書き換えてください。

続いてvim Gemfileとし、ruby 2.4.1と書いてある部分をruby -vで出てきた値(例: 2.3.1)に書き換えてください。

ターミナル | ④データベース作成~初期データ投入
1
rails db:create && rails db:migrate && rails db:seed

環境構築が完了しました。と表示されると、
本当にrails applicationが動作するかrails sコマンドで起動しましょう。

ターミナル | ⑤サーバー起動
1
rails s

rails sを起動し、ブラウザでlocalhost: 3000と入力して下記のような画面が出てくれば環境構築完了です!

環境構築

createアクションを確認してみよう

まず現在のusersコントローラーのcreateアクションがどのように書かれているか確認してみましょう。

users_controller.rb -->
1
2
3
4
def create
  User.create(params[:user])
  redirect_to root_path
end

投稿フォームはform_forで記述しているのでparamsはparams[:user]と指定する必要があります。
これで投稿フォームの内容はparamsで取得できるので、このようにかけば投稿フォームの内容がデータベースに保存されるはずです。
それではトップページから「ユーザー登録」をクリックし、実際に投稿をしてみましょう。

params

フォームに入力し、送信ボタンを押すと下のようなエラーが出てしまいました。

エラー画面

これはストロングパラメータを使っていないと出るエラーです。
このようにparamsに対してpermitメソッドを使い、保存してもいいカラムを指定しないとこのようなエラーが出てデータベースに保存されないようになっています。

それではusersコントローラーにストロングパラメータを定義してみましょう。

users_controller.rb -->
1
2
3
4
private
def tweet_pramas
    params.require(:user).permit(:name, :job_id)
end

これでnameカラムとjob_idカラムのみparamsで取得できるようになりました。
もう一度投稿をしてみましょう。

投稿画面

するとこのようにしっかりとデータベースに保存されました。

データ書き換えの危険性を確認しよう

ストロングパラメータを設定すればこのように保存されたくない情報はparamsに入りません。
ではもしストロングパラメータを設定しなかったとしたらどのようなことがおきてしまうでしょうか?
検証モードで実行してみましょう。

投稿フォームに下記のように入力してください。

投稿フォーム

今回はこのフォームを書き換えてみます。
右クリックで検証モードを選択し、検証モードを表示させてください。

検証モード

検証モードではソースを書き換えることができます。
下記のように編集をしてみましょう。

編集

user[name]の部分をuser[job_id]に、下のuser[job_id]の部分をuser[name]に変更してください。
本来であればnameカラムに3が、job_idには1が保存されるはずです。
それでは投稿をしてみましょう。

投稿

このようにjob_idで指定した1という数字が保存されてしまいました。
これがもしユーザーの情報に管理者か一般ユーザーかを識別するカラムがあったとして、管理者が0、一般ユーザーが1で登録できた場合、ここでカラムを書き換え管理者として保存されてしまうことができます。

そんな時でもストロングパラメータを設定しておけば、paramsの中に許されているカラムの情報しか入らないので、データベースには保存されなくて済みますね。

この記事のまとめ

  • ストロングパラメータは、データベースに保存するカラムを指定し、paramsで安全な情報を受け取らせる仕組みのこと
  • railsでは、ストロングパラメータを設定しないとエラーになるので注意が必要!