Rails form_withヘルパー
form_withヘルパーとは
Railsには、Viewなどから呼び出す共通処理をまとめた「ヘルパーメソッド」が用意されている!
form_withヘルパーもその1つで
セキュリティ対策などが組み込まれた安全なHTMLのformタグを作成でき、
Railsの機能を最大限生かすことが可能 🙆🏻♀️
form_withの基本形
<%= form_with do |f| %>
<% end %>
「|f|」の部分はブロック変数と言い、特定の範囲内で使える変数のことで、
今回だとform_withと同じdoからendまでの範囲で使うことができる変数のこと。
この基本形から、モデルとの連携・どのURLへデータを送るのか・どのHTTPメソッドで送るのかなどを定義し、実際に作るアプリケーションの要件に合わせてフォームの作成を行う!
フォームの要素を作成する
フォームからデータを送信した後にデータベースへ保存する必要がある場合
モデルと連携を行う必要があり、その情報を含めるとform_withは次のようになる!
基本形からListモデルと連携したform_with
<%= form_with model: List.new do |f| %>
<% end %>
「List.new」とは?
「List.new」と定義することで、Listモデルの情報をもとに
新しくオブジェクトが作成され、Listモデルに存在するtitle・bodyが格納できるようになる。
form_withはこのようにモデルと連携することで、データを簡単に保存ができたり
後の章で紹介するバリデーションなどを簡単に設定することができる!!
modelオプションでList.newを設定するだけで、
自動的CreateアクションのURLへ送信することができるということになる。
フォームに部品を追加する
form_withの範囲の中に、テキストフィールドや送信ボタンなどの部品を追加していく!
使用場面 | SampleAppでの使用箇所 | モデルオブジェクト |
---|---|---|
単一行のテキストフィールド | タイトル | text_field |
複数行のテキストフィールド | 本文 | text_area |
送信ボタン | 「投稿」ボタン | submit |
これらのモデルオブジェクトを作成するために、form_withヘルパーの部分で紹介したブロック変数「f」を使用する。
<h1>新規投稿</h1>
<!-- form_with部分 -->
<%= form_with model: List.new do |f| %>
<h4>タイトル</h4>
<%= f.text_field :title %>
<h4>本文</h4>
<%= f.text_area :body %>
<%= f.submit '投稿' %>
<% end %>
このブロック変数「f」には設定したmodelの情報(今回であればList.new)も含まれているため
後で行う保存機能を追加する際にも簡単且つ安全にデータベースに保存することができる!
コントローラーに記述を追加する
ここまでViewファイルのform_withに直接List.newとモデルの情報を渡していたが、
通常このような記述は行わず、
基本的にモデルなどの処理はViewではなくコントローラーに記述する必要があるため、
インスタンス変数という機能を用いてコントローラーで記述した値をViewで呼び出せるようにする!
インスタンス変数とは
コントローラーアクションとViewファイルでデータの受け渡しができる変数のこと。
@helloのように変数名の先頭に「@(アットマーク)」を付けることでインスタンス変数となる!
コントローラー・アクション
def new
@hello = "Hello"
end
インスタンス変数を定義
👇
viewファイル
<%= @hello %>
ブラウザに Helloと出力される
ローカル変数とは
ローカル変数とは、インスタンス変数の逆でコントローラーとViewファイルでデータの受け渡しができない変数のこと。
インスタンス変数とは違い、変数名の先頭に何も付けない場合はローカル変数となる!
コントローラー・アクション
def new
hello = "Hello"
end
インスタンス変数を定義
👇
viewファイル
<%= hello %>
表示することができず、エラーが発生する!
まとめ
インスタンス変数
- 変数の名前の先頭に@マークをつける
- コントローラーとViewでデータの受け渡しができる
ローカル変数
- 変数の名前の先頭には何もつけない
- コントローラーとViewでデータの受け渡しができない
newアクションに記述を追加する
form_withに記述していたList.newをインスタンス変数を用いて
コントローラーのnewアクションに定義しViewの記述の書き換えを行う。
インスタンス変数@listを定義し、List.newを格納する!
class ListsController < ApplicationController
def new
# Viewへ渡すためのインスタンス変数に空のModelオブジェクトを生成する。
@list = List.new
end
end
Viewファイル(new.html.erb)の記述も変更する!
<h1>新規投稿</h1>
<%= form_with model: @list do |f| %>
<h4>タイトル</h4>
<%= f.text_field :title %>
<h4>本文</h4>
<%= f.text_area :body %>
<%= f.submit '投稿' %>
<% end %>
form_withについての補足
作成したform_withには、List.newとモデルと連携させることにより、送信先のURLを判別するものだったが、慣れる前からこの省略形で扱うと、意図しない問題の原因にもなるので、厳格な書き方にまずは慣れるようにする!
厳密な記述への修正を行うため、Viewファイルの編集をする。
使用する2つのオプション
- url
どのURLへフォームの情報を送信するか - method
HTTPメソッドを指定
<h1>新規投稿</h1>
<!-- form_withにオプション追記 -->
<%= form_with model: @list, url: '/lists', method: :post do |f| %>
<h4>タイトル</h4>
<%= f.text_field :title %>
<h4>本文</h4>
<%= f.text_area :body %>
<%= f.submit '投稿' %>
<% end %>
form_withについて注意
tableタグの中でform_withを使う場合の注意点
書く位置によってはformタグがうまく生成できずフォームがうまく機能しないことがある。
1. tableタグ直下にform_withを使っている
2. trタグ直下にform_withを使っている
formタグが子要素を持たないまま生成されてしまうので
使い方に気を付ける!
課題やりながらインスタンス変数等`が理解できてなかったから復習!
色々とファイルが多くて呼び出したりするのが複雑でここらへんちゃんと理解していないとだめだ〜〜
でも少しずつわかってきてる感じがして楽しい!
頑張ろう!
Discussion