Rails Tutorial 7章 ユーザー登録フォーム(フォームの作成・送信)
ユーザー登録フォーム
1、form_forを使う
Railsに元々あるヘルパーメソッド。
まず、登録フォームのアクションから設定
app/controllers/users_controller.rb def new @user = User.new end
んで、これがフォーム
app/views/users/new.html.erb <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.email_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div>
2、フォームHTML
先ほど作成したフォームを理解するため、細かく見ていく。
<%= form_for(@user) do |f| %> . . <% end %>
・do は、form_forが一つの変数を取るブロックを表す。
・fオブジェクトは、HTMLフォーム要素(textfieldとか)に対応するメソッドが呼び出されると、@userの属性を指定するために特別に設計されたHTMLを返す。
つまり、これでは
<%= f.label :name %> <%= f.text_field :name %>
Userモデルのname属性を設定する、ラベル付きテキストフィールドを返す。
こんなHTMLを生成してるよ
<label for="user_name">Name</label> <input id="user_name" name="user[name]" type="text" />
重要なのが、inputごとにあるname属性
これ
<input id="user_name" name="user[name]" - - - /> . . <input id="user_password" name="user[password]" - - - />
これは、Railsがnameの値を使って初期化したハッシュをparams変数経由で構成するもの。nameの値がparamsで受け取れる。んだと思う
次に、formタグ自身
<form action="/users" class="new_user" id="new_user" method="post">
action = " /users "
method = " post " この二つが重要。
form_forはこれを勝手に生成してくれる。
3.1、ユーザー登録失敗
こんな感じで作る
createアクションでフォーム送信を受け付ける
↓
User.newで新しいオブジェクトを作成
↓
ユーザーを保存(または失敗)
↓
再度、送信用のユーザー登録ページを表示
まず、createアクションを作る(途中まで)
app/controllers/users_controller.rb def create @user = User,new(params[:user]) if @user.save #保存の成功をここで扱う else render 'new' end end
深く理解するため、デバック情報を参照してみる
"user" => { "name" => "Foo Bar", "email" => "foo@invalid", "password" => "[FILTERED]", "password_confirmation" => "[FILTERED]" }
ここでは、params[:user]に複数のハッシュが含まれている。フォーム送信の結果が、送信された値に対応する属性とともにuserハッシュに保存されている。
ハッシュのキーは、inputタグにあったnameの値。
ちなみに、この二つは同義
@user = User.new(params[:user])
@user = User.new(name: "Foo Bar", email: "foo@invalid", password: "foo", password_confirmation: "bar")
けど、前者のコードではセキュリティ面で懸念があるっぽい。
そこで登場するのがStrongParameters
3.2、Strong Parameters
まず、マスアサインメントってやつ
次のコードみたいに、値のハッシュを使ってRubyの変数を初期化するもの
@user = User.new(params[:user])
マスアサインメントでは、name, emailとかの他に、actionやcontrollerといった全ての値が飛んでくる。
paramsハッシュ全体を初期化するのは危険すギル。マスアサインメント脆弱性(admin=管理者権限 があればparamsの中身を見れるし自由にシステムを操作できるっぽい)。
今は、マスアサインメントを使うとRailsが怒る。
そこで、StrongParametersを使用
これを使うことで、必須のパラメーターと許可されたパラメーターを指定することができる。って何?
→簡単に言うと、DBへ入れたり更新したりする値を制限できるらしい
<使い方>
①requireでPOSTで受け取る値の設定
②permitで許可するカラムを設定
例えば、「user属性を必須にして、名前・アドレス・パスワード・パスワードの確認だけ更新許可したい!」ってとき
params.require(:user).permit(:name, :email, :password, :password_confirmation)
ここで、このパラメーターを使いやすくするため、巷では user_paramsとかいう外部メソッドが使われているらしい。
主に params[:user] の代わりとして使われる
@user = User.new(user_params)
これを、外部ユーザーに漏れないよう、privateに隠す
app/controllers/users_controller.rb . . def create @uer = User.new(user_params) if @user.save #保存の成功をここで扱う else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end