2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す 119(filter_paramters 編)

Posted at

はじめに

Rails 6 に追加された新機能を試す第119段。 今回は、filter_parameters 編です。
Rails 6 では、 filter_parameters で proc を使って、フィルターしたときに、パラメータが配列になっているときに、フィルターされないというバグが修正されています。

Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)

$ rails --version
Rails 6.0.2.1

今回は、User を2つ登録する画面を作って、その動作を確認します。
なお、 filter_parameters の動作を確認するための手抜き実装になってます。

Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

$ rails new rails_sandbox
$ cd rails_sandbox

User モデルを作る

name を持つ User モデルを作成します。

$ bin/rails g model User name

Controller と View を作る

User の controller と View を作ります。 View は手抜き実装で、 一覧画面 (index) と 登録画面 (new) だけです。

$ bin/rails g controller Users index new

routes を定義する

User 用にルーティングを定義します。 これまた、手抜き実装で、 index, new, create の3つだけにします。

config/routes.rb
Rails.application.routes.draw do
  resources :users, only: %i[index new create]
end

一覧画面 (index) を作成する

一覧画面を作成します。これまた、 table タグも使わない手抜き実装です。

Username を1件ずつ表示します。

画面の下に、登録画面へのリンクを表示します。

app/views/users/index.html.erb
<h1>Users#index</h1>

<% @users.each do |user| %>
  <p>
    <%= user.name %>
  </p>
<% end %>

<%= link_to 'New', new_user_path %>

登録画面 (new) を作成する

登録画面を作成します。ここで、今回の機能を試すためにパラメータの値が配列になるようにします。
(結果として2件のデータを登録することになります。)

パラメータが配列となるように、form.text_field の引数が name="names[]" としていることに注意してください。
これが、今回の機能を試すために必要なことの1つです。

app/views/users/new.html.erb
<h1>Users#new</h1>

<%= form_with url: users_path do |form| %>
  <p>
    <%= form.text_field name="names[]" %>
  </p>
  <p>
    <%= form.text_field name="names[]" %>
  </p>
  <%= form.submit %>
<% end %>

UsersController を完成させる

今回の機能を確認するために、完成させる必要は無いのですが、一応、動作するように実装します。
これまた、手抜き実装です。

index メソッドでは、全データを取得します。
create メソッドでは、パラメータを元にして User をデータベースに保存し、一覧画面にリダイレクトします。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def new
  end

  def create
    params[:names].each do |name|
      User.create(name: name)
    end
    redirect_to users_path
  end
end

filter_parameters を指定して、 names パラメータの値がフィルタリングさせる

いよいよ、今回の機能を確認するために、 filter_parametersnames パラメータの値をフィルタリングさせます。

proc を追加していることに注意してください。

config/application.rb
...
module App
  class Application < Rails::Application
    ...
    config.filter_parameters << lambda do |key, value|
      if key =~ /names/
        value.replace('[FILTERED]') if value.respond_to?(:replace)
      end
    end
  end
end

マイグレーションを実行する

$ bin/rails db:create db:migrate

rails server を実行して、登録画面から登録する

bin/rails s を実行し、 http://localhost:3000/users/new にアクセスし、2つのフィールドに適当に入力して、 Save ボタンを押します。

このとき、コンソールでは、 names パラメータが、 [FILTERED] となっていることに注意してください。

Started POST "/users" for 192.168.16.1 at 2020-01-25 02:48:55 +0000
Processing by UsersController#create as JS
  Parameters: {"authenticity_token"=>"..., "names"=>["[FILTERED]", "[FILTERED]"], "commit"=>"Save "}
     (0.2ms)  BEGIN

Rails5 では

Rails 5.2.4.1 では、 フィルターされず、そのまま画面で入力した値が表示されてしまいます。

Started POST "/users" for 192.168.0.1 at 2020-01-25 01:42:25 +0000
Processing by UsersController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"..., "names"=>["aaa", "bbb"], "commit"=>"Save "}

あくまで手抜きのコードです

実際のアプリでは、複数のデータを1つの画面で登録する場合には、 Form オブジェクトを使ったり、Validation を追加したり、Strong Paramters を使ったりすると思います。
今回は、あくまでも、機能の確認のための実装なので、そういった点は、すっとばして、手を抜いてます。
このままコードを再利用することはオススメしません。

試したソース

参考情報

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?