Posted at

Rails4においての form_for 最低限の使い方まとめ

More than 3 years have passed since last update.


:ballot_box_with_check: form_for メソッド

Railsではrenderなどを筆頭に、何かとよしなにやってくれるヘルパーメソッドがたくさんありますよね。

便利メソッドのおかげでユーザ登録フォームを一瞬で実装できたりと、Railsの生産性に驚くことが多いです。

ただ何かとよしなにやってくれすぎるおかげで、どういうパラメータの受け渡しをしているかのかをラップ(隠蔽)しすぎて、中身で何をやっているかがわからないままに実装できてしまったというケースもあると思います。(特に私のようにチュートリアルを見ながら勉強している人たちは...)

今回はフォーム作成のための便利メソッド、form_forについて自分なりにまとめてみることにしました。


:ballot_box_with_check: お名前登録フォームを爆速で作ろう!!!

早速フォームを作ってみましょう。

ただし、単純化のために、今回用意したパラメータは一つ、名前のみです!!簡単でしょ??

スクリーンショット 2015-07-22 17.28.19.png

このフォームを作るために必要なViewでのコードはこれだけです(Haml)↓

%h1 Write your name!

= form_for @user do |f|

= f.label :name, "名前"
= f.text_field :name

= f.submit "Send"

これで生成されるHTMLはどうなるかというと...

<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post">

<input name="utf8" type="hidden" value="&#x2713;" />
<input type="hidden" name="authenticity_token" value="A5DQ4pmpmwnCYWind+TOL4SWMQm46kGWZVLXypyC8b9B4Z9GlzTjWG8NTqvs2cqg1bEEJ6Eq0kybasumXsPLGA==" />
<label for="user_name">名前</label>

<input type="text" name="user[name]" id="user_name" />
<input type="submit" name="commit" value="Send" />

Railsのよしなに力すごいですね。これだけのコードを生成してくれます。

form_forでは、渡したオブジェクト(今回では@user = User.new)に応じて、そのオブジェクトがどのモデルに属したオブジェクトなのかを勝手に判断してくれます。


:ballot_box_with_check: Controller部分

今度はデータの受け取りのためにControllerに移ります。

class UsersController < ApplicationController

def new
@user = User.new
end

def create
@user = User.new(params[:user])
@user.save
redirect_to new_user_path
end
end

Controller部分で@user変数を作ってUserモデルのオブジェクトを入れておきます。この@user変数をviewでform_forに渡すことによって、フォームが動作するようになります。

また、アクション名をnewにすることにより、new.html.hamlのファイルを勝手に探しに行ってくれます。

それでは先ほど生成されたフォームに戻って、この部分。フォームのテキストエリアに入ったパラメータは、name属性から引っ張ってくることができます。

<input type="text" name="user[name]" id="user_name" />

みたところ、params[:user]みたいな感じでパラメータを取得できそうです。

しかしこれで実際にフォームの値を送信してみると...

スクリーンショット 2015-07-22 17.58.39.png

現在ではこのデータの受け取り方は禁止されています。エラーもForbiddenと、禁止の意を表しています。

昔のRailsではこれでいけたみたいなのですが、Rails4では引数に対する制限が厳しくなりました。

理由は、Userモデルが管理者を区別するadmin属性を持っていて、curlコマンドなどでadmin: trueのような属性を送った場合、管理者権限を持ったアカウントを作ることができてしまい、セキュリティホールに繋がるからです。

なので、現在のRailsでは基本的にStrongParametersという概念を用います。

とはいっても名前の通りで、パラメータ受け取りの制限を強くするよ!!というものです。

StrongParametersを適用すると、以下のようなControllerになります。

class UsersController < ApplicationController

def new
@user = User.new
end

def create
@user = User.new(user_params)
@user.save
redirect_to new_user_path
end

private

def user_params
params.require(:user).permit(:name)
end
end

params.require(:user).permit(:name)の部分で、name属性しか受け取らないという指定をすることが原則になりました。


:pray: 完成!!

以上のコードで、本当に最低限のform_forヘルパーメソッドによるフォームの実装が完了します。

一応ちゃんと実装できてるか試してみます。

簡易コンソール用にDBに登録した名前を引っ張ってきてます。

jlACGMRUdt.gif

息をするようにフォームが作れるようになるといいですね。form_tagヘルパの使い方はまだわかってないですが、またの機会に...