web系エンジニアを目指す私、siが学習のアウトプットをメインにプログラミングについての記事を書いていきます。

【form_with】基本的な書き方・複数のモデルを引数に指定(ネスト)する書き方

 
この記事を書いている人 - WRITER -

 

こんにちは!

web系エンジニアを目指して学習中のsiと申します^ ^

 

この記事の対象者

  • 基本的なform_withの書き方(旧form_tag, 旧form_for)を知りたい方
  • ルーティングがネストしている場合に、複数のモデルを引数に指定する書き方を知りたい方

 

form_withとは

 

Rails5.1から追加されたフォーム作成を行うためのヘルパーメソッドのことです。

それ以前では、データの保存を伴わない場合はform_tag

データの保存を伴う場合はform_forを使用していました。

 

Rails5.1以降では、

データの保存を伴わない場合も、データの保存を伴う場合もform_with1つで実装出来るようになりました。

 

そのため、form_withの書き方には、

  • データの保存を伴わない書き方(旧form_tag)
  • データの保存を伴う書き方(旧form_for)

の2種類があります。

 

また、データの保存を伴う書き方には、

  • 引数に1つのモデルを指定する方法
  • 引数に複数のモデルを指定する方法

があります。

 

データの保存を伴わない場合の書き方(旧form_tag)

 

基本的な書き方はこんな感じです。

<%= form_with url: "パス" do |form| %>
  フォームの内容
<% end %>

 

例えばposts_pathに対して「title」の情報を送信したい場合、このように書きます。

<%= form_with url: posts_path do |form| %>
  <%= form.text_field :title %>
  <%= form.submit %>
<% end %>

これでurl(posts_path)に対して、text_fieldに入力された「title」の情報を渡すことが出来ます。

 

データの保存を伴う書き方(旧form_for) 引数に1つのモデルを指定

 

基本的な書き方はこんな感じです。

<% form_with model: モデルクラスのインスタンス do |f| %>
  フォームの内容
<% end %>

 

例えばpostモデルのインスタンスを保存・更新させるフォームを書く場合、このように書きます。

<%= form_with model: @post do |f|%>
  <%= f.label :title, "タイトル" %>
  <%= f.text_field :title%>
  <%= f.label :body, "本文" %>
  <%= f.text_area :body%>
  <%= f.submit "送信"%>w
<% end %>

 

1行目には、postコントローラのnewアクション又はeditアクションで定義したインスタンス(@post)が引数として渡されています。

# posts_controller.rb

def new
  @post = Post.new
end

def edit
  @post = Post.find(params[:id])
end

@postの中身が空(new)の場合はcreateアクションが呼ばれ、

中身が入っている場合(edit)の場合はupdateアクションが呼び出されます。

 

form_withではこのように自動的にインスタンスの中身を判断して、次に行うアクションを決定してくれます。

 

 

データの保存を伴う書き方(旧form_for) 引数に複数のモデルを指定

 

下記のようにルーティングでネストをしている場合に、

# routes.rb

resources :posts do
  resources :comments, only: [:edit, :update, :create, :destroy]
end

commentモデルクラスのインスタンスを保存・更新したい場合、

form_withに2つの引数を指定する必要があります。

<%= form_with model: [@post, @comment] do |f| %>
  <%= f.text_area :body, placeholder: "コメントする" %>
  <%= f.submit "SEND" %>
<% end %>

 

ルーティングのネストについては、こちらの記事で解説しています♪

【Rails】基本的なルーティングの書き方、ネスト・resourcesについても解説

 

2つの引数を渡したい場合、アクションにも2つのインスタンスを定義します。

# posts_controller.rb

def show
  @post = Post.find(params[:id])
  @comment = Comment.new
end
# comments_controller.rb

def edit
  @post = Post.find(params[:post_id])
  @comment = Comment.find(params[:id])
end

複数のモデルクラスインスタンスを渡す場合、

2つ目の引数(@comment)の中身が空のときはcreateアクションが実行され、

中身が入っているときはupdateアクションが実行されます。

 

まとめ

 

  • form_withとはRails5.1から使用出来るようになったヘルパーメソッドで、以前はform_forとform_tagが使われていた
  • ルーティングをネストしている場合は、引数に指定するモデルを複数指定する必要がある

 

参考記事

 

 

この記事を書いている人 - WRITER -

- Comments -

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


Copyright© .i DO WHAT I WANT , 2022 All Rights Reserved.