ドキュメントを読み込むのは大事、ということでRailsガイドを頭から読んでいく取り組みをしています。 各章ごとに、(Railsガイドにちゃんと書いてあるのに)知らなかった機能を雑にまとめていきます。
今回は、Action Controller の概要の章です。
wrap_parameters
リンクはこちら
パラメータを受け取るときに、パラメータがコントローラに応じたキー名でラップされるようになる。
これはデフォルトではJSONのリクエストの場合は機能するようになっているようです。
例えば、JSONで{"title":"value1", "content":"value2"}
を送ると、rails側で"book"=>{"title"=>"value1", "content"=>"value2"}
のようにラップしてくれました。
ちなみに、falseを指定すると無効にできるみたいです。
class BooksController < ApplicationController wrap_parameters false end
extract_value
リンクはこちら
Rails7.1から入ったメソッド。
複合主キーを持つモデルのため、1つのパラメータから値を配列にして返してくれます。
params #=> #<ActionController::Parameters {"controller"=>"books", "action"=>"show", "id"=>"2_4"} permitted: false> params.extract_value(:id) #=> ["2", "4"]
permit!
リンクはこちら
パラメータのハッシュ全体を許可したい場合に使えます。
当然、セキュリティ面には注意する必要があります。
params #=> #<ActionController::Parameters {"authenticity_token"=>..., "book"=>{"title"=>"本1", "content"=>"コンテンツ"}, "commit"=>"Create Book", "controller"=>"books", "action"=>"create"} permitted: false> params.permitted? #=> false params.permit! #=> #<ActionController::Parameters {"authenticity_token"=>..., "book"=>#<ActionController::Parameters {"title"=>"本1", "content"=>"コンテンツ"} permitted: true>, "commit"=>"Create Book", "controller"=>"books", "action"=>"create"} permitted: true> params.permitted? #=> true
flash.keep
リンクはこちら
flashを次のリクエストに引き継ぐ時などの使える、flashの寿命を伸ばすようなメソッドです。
scaffoldしたアプリで、show
アクションにflash.keep
と書いたら、create
した後に何度リロードしてもフラッシュメッセージが表示されました。
before_actionのためのbeforeメソッドなど
リンクはこちら
例えばbefore_action
の処理内容を別クラスで実行するときにはbefore
という名前のクラスメソッドを、コントローラのインスタンスを引数に渡す形で作ってあげれば実行できるみたいです。
知らなかったですが、どこかで使える場面がありそうだなと思いました。
class Sample def self.after(controller) p 'after actionが実行された' end end
以下のようにきちんと実行されていました。
Started GET "/books/1" for ... Processing by BooksController#show as HTML Parameters: ... Rendering layout layouts/application.html.erb Rendering books/show.html.erb within layouts/application Rendered books/_book.html.erb (Duration: 1.3ms | Allocations: 179) Rendered books/show.html.erb within layouts/application (Duration: 6.8ms | Allocations: 1202) Rendered layout layouts/application.html.erb (Duration: 61.4ms | Allocations: 13927) "after actionが実行された" Completed 200 OK in 79ms (Views: 66.6ms | ActiveRecord: 3.4ms | Allocations: 18000)
authenticate_or_request_with_http_token
リンクはこちら
トークン所有の有無で認証するBearerトークンを利用可能にするもの。
Railsガイドのようにサンプルコードを書いて動かしたら、確かにアクセスできなくなりました。
HTTP Token: Access denied.
ライブストリーミング
リンクはこちら
ActionController::Live
を使うことでライブストリーミングを利用できるようになります。
例えば以下のように書いたら、1秒ごとに現在時刻が表示されました。
def show response.headers['Content-Type'] = 'text/event-stream' 100.times { response.stream.write "#{Time.current}\n" sleep 1 } ensure response.stream.close end
filter_parameters
リンクはこちら
ログに出力される情報をfilter_parameters
で制御できます。
私がrails new
した環境では、デフォルトでconfig/initializers/filter_parameter_logging.rb
に以下のように記載されていました。
# Be sure to restart your server when you modify this file. # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. # Use this to limit dissemination of sensitive information. # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ]
試しに、ここに:title
を追加してログを見てみたところ、以下のように[FILTERED]
となっていました。
デフォルトの設定のままになっていることも多そうなので、一度自分のアプリケーションを見直してみても良さそうだなと思いました。
Started POST "/books" for ... Processing by BooksController#create... Parameters: {"authenticity_token"=>"[FILTERED]", "book"=>{"title"=>"[FILTERED]", "content"=>"内容4"}, "commit"=>"Create Book"} ...