LoginSignup
18
20

More than 5 years have passed since last update.

Railsのparamsはキーの型に関係なく値を取り出すことができる

Last updated at Posted at 2018-09-29

この記事で紹介すること

paramsHashではなくActionController::Parametersのインスタンスのため、キーの型がStringSymbolかを区別することなく値を取ってくることができます。

開発環境

ruby2.5.1
rails5.2.1

paramsはキーがStringかSymbolかを区別しない

rubyでは、Hashはキーの型を区別するため、以下のように動作します。

#rubyでは...

h = { :last_name => "佐藤", "first_name" => "太郎" }

#キーに指定した要素の型で値を取ってくることができる
h[:last_name]   #=> "佐藤"
h["first_name"] #=> "太郎"

#指定した要素とは違う型で値を取ってくることはできない
h["last_name"] #=> nil
h[:first_name] #=> nil

ところが、railsのparamsActionController::Parametersのインスタンスであり、Hashの機能が拡張されているためキーの型に関係なく値を取ってくることができます。

#railsで受け取ったparams
params
  => <ActionController::Parameters {"last_name"=>"佐藤", "first_name"=>"太郎"}>

#paramsの見た目はHashだが、ActionController::Parametersのインスタンス
params.class
  => ActionController::Parameters

#キーの型に関係なく値を取ってくることができる!
params["last_name"]  #=> "佐藤"
params["first_name"] #=> "太郎"
params[:last_name] #=> "佐藤"
params[:first_name] #=> "太郎"

追記 paramsの型をHashに変換するには?

以下、この記事を読んでいただいた経験豊富なエンジニアの方から教わった知見です。
マスアサインメントによる事故を防ぐためにRails4以降ではparamsを直接Hashに変換することは出来なくなっています。

#適当にparamsのようなインスタンスをつくる
pry(main)> params = ActionController::Parameters.new(:hoge => :huga, 'foo' => 'bar')
 => <ActionController::Parameters {"hoge"=>:huga, "foo"=>"bar"} permitted: false>

#外部から入力できるparamsのマスアサインメントによる事故を防ぐために
#そのままではハッシュにならない(Rails4よりも前のバージョンではこれでも変換できた)
pry(main)> params.to_h
 => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

#明示的に許可したものだけハッシュになる
pry(main)> params.permit(:hoge).to_h
 => Unpermitted parameter: :foo    # :foo は許可されないため捨てられる
 => {"hoge"=>:huga}                # :hogeは許可されるためハッシュ化する

pry(main)> params.permit(:hoge, :foo).to_h
  => {"hoge"=>:huga, "foo"=>"bar"} # 全てハッシュになる

#危険なのを分かっていて、無理やりハッシュにしたい時
# やりかた1
pry(main)> params.to_unsafe_h
  => {"hoge"=>:huga, "foo"=>"bar"}

# やりかた2
pry(main)> params.permit!
  => <ActionController::Parameters {"hoge"=>:huga, "foo"=>"bar"} permitted: true>
pry(main)> params.to_h
  => {"hoge"=>:huga, "foo"=>"bar"}

参考サイト
・ActionController::Parametersの内部実装など
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/hash_with_indifferent_access.rb

・マスアサインメントについて
https://railstutorial.jp/chapters/sign_up?version=4.2#sec-strong_parameters
https://railsguides.jp/action_controller_overview.html#strong-parameters

18
20
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
18
20