はじめに
form_withとは、Railsでデータを送るときに使うヘルパーメソッドです。
このform_withを扱う時に、初心者の私が勘違いしていたことや、うっかり忘れてしまいがちだった部分をご紹介します。
1. modelで渡している@listとかって何者なのか
<%= form_with model: @list do |f| %>
<% end %>
form_withで新規登録フォームを表示したり編集用のデータを呼び出したりするためには、オブジェクトに紐づける必要があります。
新しくデータを作りたいときは、
List.new
更新をしたいときはどのデータを編集するか判別するために
List.find(1)
などをこのmodel部分で指定します。
これをコントローラから指定するために、
def new
@list = List.new
end
def edit
@list = List.find(params[:id])
end
のように@listとしてform_withにデータを渡すことで、新規作成の場合は「保存先の準備」を、編集の場合は「編集したいデータの表示」をすることが出来ます。
form_withを使ってデータの編集画面を表示したい場合は、元々登録されているデータを表示する必要があります。
例えば、
def edit
@list = List.find(params[:id])
end
<%= form_with model: @list do |f| %>
<%= f.text_field :title %>
<% end %>
この場合、List.find(params[:id])に登録されているtitleが参照されることになります。
お恥ずかしながら私は最初の頃、この@listが何を表しているのか分からずなんとなくで付けていました。
例えば、一覧ページに新規作成フォームと一覧表示用のデータを用意したい場合、
def index
@lists = List.all
@list = List.new
end
のように記述したときにform_withへ@listsを記述してしまったりと、データの渡し方に混乱していました。
今は当時より理屈が分かってきたので間違えることも少なくなりましたが、学習の際は混乱を避けるために、新規作成のモデルオブジェクトを@list_newとするのもありだなと感じています。
def index
@lists = List.all
- @list = List.new
+ @list_new = List.new
end
頭の回転が速い方には何てことのない部分なのかもしれませんが、複数形と単数形の扱いや見分けも、理屈が理解しきれていない初心者には難しかったです…。
2.編集フォームのvalueにデータを渡す
form_withからデータを渡したのと同じように、Itemに紐づけたtagsをフォームに表示したいときはvalue: @tag_listのように呼び出すことができます。
def edit
@item = Item.find(params[:id])
@tag_list = @item.tags.pluck(:name).join(',')
end
<%= form_with model: @item do |f| %>
<%= f.text_field :name %>
<%= f.text_field :tag_name, value: @tag_list %>
<% end %>
ちなみに、<%= f.text_field :tag_name, value: @item.tags.pluck(:name).join(',') %>で直接ビューから指定することもできました。
@itemなどのインスタンス変数を使ったデータの作り方や渡し方が少しずつ分かってきました。
学習3か月目にしてようやく、インスタンス変数ってなんて便利なんだ!と実感してきています笑
3.urlとmethodのオプションを設定する
form_withでは、urlとmethodのオプションを追加することで、厳密にどのアクションへデータを送信するか指定することが出来ます。
<%= form_with model: @list, url: '/lists', method: :post do |f| %>
<% end %>
form_withからデータが上手く渡せない…!というときは、データの送信先が間違っている可能性もあるので、このurlの部分は要チェックです。
私は何度もここでつまづきました。
特に、似たようなフォームだからコピペで作っちゃえと思って作成したときに失敗しがちです。
原因が単純なだけに、もったいないですね。
ちなみに…form_withでurlを指定する際にlists_pathのようにRailsのヘルパーメソッドを使用する際は、''が不要になります。
<%= form_with model: @list, url: lists_path, method: :post do |f| %>
<% end %>
こんな感じです。
私はここを「url: 'lists_path'」と書いてしまいがちで、なぜか謎のURLを探しに行ってしまう…何故なんだ…となりがちでした。
こちらも足止めされがちなうっかりポイントだったので、初心者の方はお気を付けください。
おわりに
私の場合、最初に学んだ時よりだいぶ時間が経ってから、あれってそいうことなのか…!すごい便利だ!と、何度も伏線回収をしながら感動を覚えています。
基礎が身についていないことをひしひしと感じているので、これからも定期的に戻ったり進んだりしながら確認作業を続けていこうと思います。