22
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails:form_withのオプションや特徴について整理

Last updated at Posted at 2021-02-04

※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog

Railsでフォームを作成するときに使用するform_withメソッドについて整理しました。

form_withメソッドとは

Railsで用意されているヘルパーメソッドの1つで、投稿ページなどでのフォームの実装に役立ちます。
ヘルパーメソッドとは主にビューでHTMLタグを出現させたりテキストを加工するために使用するメソッドの総称です。

基本構文

form_withの基本構文は以下の通りです。モデルかスコープかURLは必ず記述します。

form_with(モデル or スコープ or URL [, オプション])

form_withに記述するオプション

他にもいくつかオプションはありますが、ここではよく使うもの紹介します。

オプション 説明 デフォルト値
:model モデルを指定
:scope スコープを指定
:url URLを指定
:local リモート送信の無効 false
:method HTTPメソッドを指定 POST
:id id属性を指定
:class class属性を指定

localオプションについて

:localはリモート送信(Ajax通信のような非同期通信)によるフォームの送信の有効・無効を設定するオプションです。

JavaScriptでAjax通信によるフォームの送信を実装する場合などは、何も記述しなくてOKです。

逆に、ブラウザの読み込みをするような同期通信を実装する場合は、local: trueと記述して、リモート送信をオフにします。

※参考記事:[Qiita【Rails】form_withに記述するlocal: trueについて]
(https://qiita.com/sho_tsuchida1105/items/b08df35fe3c45f3756da)

form_withメソッドの便利な機能

form_withには、モデル(:model)で記述した場合の便利な機能があります。

引数として渡されたモデルクラスのインスタンスに中身が入っているか否かで、フォーム送信後のアクションをcreateかupdateに自動的に振り分けてくれることです。

インスタンスに中身が入っていない場合はcreateアクションへ、中身が入っている場合はupdateアクションへ処理を振り分けてくれます。

以下のようなfruits_controller.rbがあるとします。

app/controllers/fruits_controller.rb
class FruitsController < ApplicationController
  before_action :set_fruit, only: [:create, :update]

  def index
    @fruits = Fruit.all
  end

  def new
    @fruit = Fruit.new# 空のインスタンスを生成
  end

  def create
    redirect_to root_path
  end

  def edit
    @fruit = Fruit.find(params[:id])# URLに含めたidから検索したレコードでインスタンスを生成
  end

  def update
    redirect_to root_path
  end

  private
  def fruit_params
    params.require(:fruit).permit(:name, :color)
  end

  def set_fruit
    @fruit = Fruit.create(fruit_params)
  end
end

以下のnew.html.erbedit.html.erbは、ほとんど同じ記述ですが、1行目の@fruitの中身の有無が異なります。

app/views/fruits/new.html.erb
<%= form_with model: @fruit, local: true do |form| %><%# @fruitの中身は空 %>
  <div class="">果物の名前</div>
  <%= form.text_field :name, class: "item-text-field" %>

  <div class="">果物の色</div>
  <%= form.text_field :color, class: "item-text-field" %>
  <%= form.submit "登録する", class: "submit-btn" %>
<% end %>
app/views/fruits/edit.html.erb
<%= form_with model: @fruit, local: true do |form| %><%# @fruitにはeditアクションで代入したレコードの値が入っている %>
  <div class="">果物の名前</div>
  <%= form.text_field :name, class: "item-text-field" %>

  <div class="">果物の色</div>
  <%= form.text_field :color, class: "item-text-field" %>
  <%= form.submit "更新する", class: "submit-btn" %>
<% end %>

new.html.erbでは、フォームを送信すると@fruitの中身が空であることを読み取ってcreateアクションに振り分けてくれます。
一方、edit.html.erbではフォームを送信すると@fruitに中身があることを読み取ってupdateアクションに振り分けてくれます。

URLを自分で指定する場合と比べて、モデルのインスタンスを引数として指定することで、記述の手間が減り、フォームの作りをそのまま転用しやすくなります。

form_tagとform_forとの違いについて

従来のform_tag、form_forとの違いについては以下の方が詳しく解説してくれているのでご参照ください。

Railsドキュメント フォーム(form)
Qiita【Rails 5】(新) form_with と (旧) form_tag, form_for の違い

22
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?