2
4

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.

「form-with」なぜ自動的にcreateアクションが呼ばれるのか

Last updated at Posted at 2022-01-03

form-withはruby on railsで使える、コードをよりシンプルに書くためのヘルパーメソッドです。
その中のひとつ、form-withのmodelオプションについて勉強していて浮かんだ疑問が、
「指定していないのに、なぜ自動的にcreateアクションが呼ばれるのか。。」
この疑問を解決するために、今回はform-withのmodelオプションの使い方と仕組みについて備忘録としてまとめます。

#form-withには2種類の書き方がある
 まずは前提として、form-withの基本的な2種類の使い方についてまとめます。
1つ目はmodelオプションを使った以下のような書き方です。

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

2つめはurlオプションでパスを指定する方法です

 <%= form_with url: root_path do |form|%>
  フォーム内容
 <%= end%>

 さてここで1つ疑問が浮かぶのが、「form_withのmodelオプションではどうやってパスの指定をするの??」という事です。urlオプションではパスの指定をしていますが、modelオプションではパスの指定をしません。結論は、「モデルのインスタンスの中身でパスが決まる」という事です。具体的には、
①インスタンスに値が入っていない場合は、createアクションが呼ばれ、
②インスタンスに値が入っている場合は、updateアクションが呼ばれます。
順番に見ていきます。
 
#modelオプション→インスタンスに中身がない場合はcreateアクションが呼ばれる
 インスタンスに中身が入っていない場合とは、以下のようにコントローラーのnewアクションで呼び出された時です。

hoges_controller
  def new 
    @hoge = Hoge.new
  end

この@hogeには何も値が入っていません。
そしてviewのnew.htmlではform_withのmodelオプションで、@hogeに値が入っていないことから、createアクションをパスに指定します。

#modelオプション→インスタンスに中身がある場合はupdateアクションが呼ばれる
 さて次にインスタンスに中身が入っている場合とは、以下のようにコントローラーのeditアクションで呼び出された時です。

hoges_controller
 def edit
  @hoge = Hoge.find(params[:id])
 end

この@hogeには値が入っています。
そしてviewのedit.htmlではform_withのmodelオプションで、@hogeに値が入っていることから、updateアクションをパスに指定します。

#まとめ
 以上form_withのmodelオプションについて、「なぜ指定していないのにcreateアクションが呼ばれるのか」という疑問についてまとめました。結論としては、
①インスタンスに値が入っていない場合は、createアクションが呼ばれ
②インスタンスに値が入っている場合は、updateアクションが呼ばれる
ということです。

今回の記事が少しでも誰かのお役に立てたら幸いです。

2
4
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
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?