11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

株式会社ラグザイアAdvent Calendar 2023

Day 12

paramsメソッドとは何か?

Last updated at Posted at 2023-12-11

はじめに

この記事は株式会社ラグザイア Advend Calendar 2023 の記事です

Ruby on Railsを用いて実装を行っているとき、controller内でよくparamsメソッドを用いて、リクエストで送られてきたデータを受け取るということをやると思います

ふと、paramsは何者で、なぜリクエストで送られてきたデータを取り出すことができるのだろう? と興味が湧いたので調べてみました

調査

https://api.rubyonrails.org/classes/ActionController/Metal.html#method-i-params-3D によると、paramsはActionController::Metal※1 のインスタンスメソッドで、以下のように定義されていました

def params
  @_params ||= request.parameters
end

@_paramsがnilでなければそのまま返し、nilの場合はrequest.parameters※2を代入して返すというものです

続いて、@_paramsのソースコードを調べてみると、ActionController::Metalのinitializeに定義されていました(https://github.com/rails/rails/blob/c80fa6a0697656a522b7688d116a9a6fca1fc0fd/actionpack/lib/action_controller/metal.rb#L185)

def initialize
      @_request = nil
      @_response = nil
      @_response_body = nil
      @_routes = nil
      @_params = nil
      super
    end

ここまでで、

  • @_paramsはActionControllerインスタンスが作成される時に定義されるインスタンス変数
  • paramsメソッドは、@_paramsを参照するメソッド

ということがわかりました。

次に、実際に手元で、リクエスト時に@_paramsに何が入るのかをみてみます

準備

rails newで検証のためのrailsアプリを作成する。アプリ名は「params_inspection」とする

params_inspects_controller.rbとparams_inspectアクションを作成し、中にdebuggerを仕込む

def params_inspect
	debugger
end

routes.rbにルート追加

get 'params_inspects/params_inspect', to: 'params_inspects#params_inspect'

これで準備ok

また、使用した環境は以下です

mac OS Ventura 13.6.1

Ruby 3.1.4

Ruby on Rails 7.1.2

実践

rails sでサーバーを立ち上げた後、postmanでリクエストを飛ばし、railsのログ内でデバッガを使ってインスタンス変数(@_params)の中身を見てみます

Started GET "/params_inspects/params_inspect?hoge=foo_1" for ::1 at 2023-12-09 14:48:57 +0900
Processing by ParamsInspectsController#params_inspect as */*
  Parameters: {"hoge"=>"foo_1"}
[1, 6] in ~/params_inspection/app/controllers/params_inspects_controller.rb
     1| class ParamsInspectsController < ApplicationController
     2|   def params_inspect
=>   3|     debugger
     4|     Rails.logger.debug "Received params: #{params.inspect}"
     5|   end  
     6| end
=>#0    ParamsInspectsController#params_inspect at ~/params_inspection/app/controllers/params_inspects_controller.rb:3
  #1    ActionController::BasicImplicitRender#send_action(method="params_inspect", args=[]) at ~/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/actionpack-7.1.2/lib/action_controller/metal/basic_implicit_render.rb:6
  # and 79 frames (use `bt' command for all frames)
(rdbg) p params    # command
=> #<ActionController::Parameters {"hoge"=>"foo_1", "controller"=>"params_inspects", "action"=>"params_inspect"} permitted: false>
(rdbg) p @_request    # command
=> #<ActionDispatch::Request GET "http://localhost:3000/params_inspects/params_inspect?hoge=foo_1" for ::1>
(rdbg) p instance_variables    # command
=> [:@_action_has_layout, :@rendered_format, :@_routes, :@_request, :@_response, :@_response_body, :@_params, :@_url_options, :@marked_for_same_origin_verification, :@_view_runtime, :@_db_runtime, :@_lookup_context, :@_action_name, :@_config]
(rdbg) p instance_variable_get('@_params')    # command
=> #<ActionController::Parameters {"hoge"=>"foo_1", "controller"=>"params_inspects", "action"=>"params_inspect"} permitted: false>

@_paramsインスタンス変数に、リクエストのパラメータが格納されたActionController::Parametersインスタンスが入っていることがわかりました

まとめ

今回のまとめです

  • paramsメソッドは、@_paramsを参照するメソッド
  • @_paramsはActionControllerインスタンスが作成される時に定義されるインスタンス変数
  • リクエスト後、@_paramsには、リクエストのパラメータが格納されたActionController::Parametersインスタンスが入っている

今度は、httpプロトコルで送られたリクエストがどのように解析されて、最終的にパラメーターがActionController::Parametersインスタンスに格納されるのか?を調べてみたいと思います

ここまで読んでいただき、ありがとうございました!

注釈

※1 ActionController::BaseはActionController::Metalを継承している

※2 request.parametersは ActionDispatch::Requestオブジェクトのメソッドで、クエリパラメータ、リクエストボディ(POSTデータ)、ルートパラメータなど、リクエストに含まれるすべてのパラメータを結合して返す(https://github.com/rails/rails/blob/c80fa6a0697656a522b7688d116a9a6fca1fc0fd/actionpack/lib/action_dispatch/http/parameters.rb#L50)

11
1
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
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?