form_for って難しい

 form_forはRailsの入力フォームを作るときにお世話になるアイツ。

 なんか自動で色々やってくれるから簡単にDBに保存できるようになるんだけれど、その自動な部分がよくわかってなくて説明を求められた時に困った。そして間違ったことを言ってしまったので、きちんと調べて要点をまとめたい。自分のために。

 

ピカわか!

https://www.pikawaka.com/rails/form_for

 このサイトがものすごい詳しくまとめていらっしゃるので、いざとなったらここを見るのがいいです。ここで書かれている内容を自分用にまとめよう。

 

 

●form_forの使い方

 

<%= form_for(@user) do |f| %>
    <%= f.text_field :name %>
    <%= f.number_field :age %>
<%= f.text_field :nickname %>          ※nicknameは保存しないものとする
    <%= f.submit %>
<% end %>

 form_forの引数の@userはモデルクラスのインスタンスをさす。つまり、Railsのコントローラーで定義されているインスタンス変数のことだ。これでDBの保存先を呼び出しているので、ここから保存先のテーブルを辿れる。

 

 <%= f.text_field :name %>でテキストフォームが作られるが、:nameは保存先のカラム名を指定している。この部分はhtmlに変換されると

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

 となる。設定したカラム名からキー名が自動で生成される。このようにキー名が特殊な形になるので、createメソッドで保存するパラメータの指定の仕方も独特になる。

 ※ちなみにこの書き方は、後述のハッシュuser: {name: "●●"} からの呼び出しである。userハッシュのキー名:nameをname属性にするよってことだろう。

 

 

●form_for のパラメーター

 

params = { user: { name: 入力した名前  , age: 入力した数字 , nickname: 内容 } }

  ※form_tag だと params = { name: "入力名前", age: "入力数字" } のように キー名:"入力内容" がパラメータの中身になりますが、

 form_forだと、モデル名(user: )をキー名として、{ カラム名:"入力内容" } がまとまったハッシュをバリューとしてパラメータが設定される。ハッシュinハッシュである。

 

 もしこれをcreateアクションで保存する記述をするとなると、

def create
User.create( name: params[:user][:name] , age: params[:user][:age], nickname: params[:user][:nickname] )
end

 このように複層的(メタ的)にキー名を呼び出さなくてはならないので冗長な書き方になってしまう。これをシンプルにしてくれるのが ストロングパラメータのrequireメソッドである。

 

def create
User.create( user_params )
end

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

 require( :user )でuserモデルを呼び出しています。 form_for (@user) でuserモデルのインスタンス変数を呼び出していますから、そことつながっていますね。これによってparams[ :user ][ それぞれのキー名 ]が呼び出せている状態です。params呼び出すと

params.require(:user) = { 
                   name: 入力した名前 ,
                   age: 入力した数字 ,
nickname: 入力した内容 }

  こうなる。これでform_tagと同じハッシュ構造になったので、あとはこのハッシュの中からキー名を呼ぶだけ。ただ、保存したくないnicknameも呼び出しているので制限をかける。それがこの後の.permitである。

 

 .permit( )の中身ではuserテーブルのカラム名を指定して許可を与えている。ハッシュ内ハッシュのキー名がカラム名になっているので、それを呼び出している。

 ※form_tagでは入力フォームのタグで記したキー名が.permit( ) の中身になりますが、違いが出ているので注意。

 

 

 

 このようにハッシュinハッシュになるから複雑になるんだな。という印象。form_tagとの違いを厳密に理解しないと。まぁ保存の作業はRailsが自動的にしてくれるから面倒はないのだけれど、中身の理解となると、自動的だからゆえに難解だね。

 

 

<参考サイト> ありがとうございました

https://www.pikawaka.com/rails/form_for (ピカわか)

https://techblog.kyamanak.com/entry/2017/08/29/012909

https://qiita.com/4npei/items/e23502d4f5e444464654

https://web-camp.io/magazine/archives/17666