はじめに
11月にリリースされたRails8では多くの新機能が追加されました。
その中でも個人的に惹かれた機能がParameters#expect
です。
この新機能は、従来のparams.require
やparams.permit
に代わり、型安全性を向上させる仕組みです。
これまではパラメータの型や構造の制御が難しいところがありました。今回のparams.expect
の追加により、より簡潔かつ明確に期待するパラメータを定義できるようになりました。
それぞれの比較をまとめてみたのでぜひ参考にしてください。
新旧比較
書き方の違い
従来はrequire
でデータのオブジェクトを決め、permit
に対応するキーを指定する形式でしたが、expect
では構造を簡潔に記載するだけでよくなります。
- 従来:
params = ActionController::Parameters.new(post: { id: 1, title: 'タイトル' }) params.require(:post).permit(:id, :title)
- 新:
params = ActionController::Parameters.new(post: { id: 1, title: 'タイトル' }) params.expect(post: [:id, :title])
該当のパラメータがない時
該当するパラメータが送信されなかった場合は、従来の方法でも新しい方法でも同じく400エラー(ActionController::ParameterMissing)が発生します。
- 従来:
params = ActionController::Parameters.new(error: { id: 1, title: 'タイトル' }) params.require(:post).permit(:id, :title) # => ActionController::ParameterMissing
- 新:
params = ActionController::Parameters.new(error: { id: 1, title: 'タイトル' }) params.expect(post: [:id, :title]) # => ActionController::ParameterMissing
パラメータが改ざんされた時
外部から送信されるパラメータが意図した構造と異なる場合、従来の方法では500エラーが発生する可能性がありました。params.expect
では400エラーに改善されています。
- 従来:
params = ActionController::Parameters.new(post: :error) params.require(:post).permit(:id, :title) # => NoMethodError (undefined method `permit' for an instance of Symbol):
- 新:
params = ActionController::Parameters.new(post: :error) params.expect(post: [:id, :title]) # => ActionController::ParameterMissing (param is missing or the value is empty or invalid: post):
パラメータの型による違い
従来のparams.permit
では型検証がないため、予期しない構造のデータを受け取る可能性がありました。
params.expect
では、配列の型チェックが可能になりました。[[ :属性名 ]]
という書き方をすることで、配列として取り扱われます。
明示的に構造が定義できるため型安全性が向上しています。
- 従来:
params = ActionController::Parameters.new(user: [{ name: "ユーザー1" }, { name: 'ユーザー2' }]) params.permit(user: [:name]) # => OK params = ActionController::Parameters.new(user: { name: "ユーザー1" }) params.permit(user: [:name]) # => OK(配列じゃなくても通過する)
- 新:
params = ActionController::Parameters.new(user: [{ name: "ユーザー1" }, { name: 'ユーザー2' }]) params.expect(user: [[:name]]) # => OK params = ActionController::Parameters.new(user: { name: "ユーザー1" }) params.expect(user: [[:name]]) # => ActionController::ParameterMissing
まとめ
Rails8で追加されたparams.expect
によって
- 型安全性の向上
- エラー処理の改善
- コードの簡潔さ
上記のようなメリットを得られることが期待できます。
ぜひRails8を使った開発をする際には利用してみてください!