Null_06
@Null_06 (Null 06)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

どうしてそこに到達するのか?

解決したいこと

Ruby on Railsでログインフォームを製作中です。
form_withを使っているときに、疑問が生まれたので質問します。

以下で定義したフォームで送信すると、Sessionコントローラのcreateアクションに到達します。生成したHTMLのログインフォームではmethodにpostが指定されています。

現状、sessionsリソースのルーティングにはGETPOSTDELETEの3つがあります。にも関わらずどうしてform_withメソッドはPOSTを指定しているのでしょうか?

ログインフォームのコード

app/views/sessions/new.html.erb
<% provide(:title, "Log in") %>
<h1>Log in</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_with(url: login_path, scope: :session) do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Log in", class: "btn btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

生成されたログインフォームのHTML

<form action="/login" accept-charset="UTF-8" method="post">
    <input type="hidden" name="authenticity_token"
           value="4d0...FFw" autocomplete="off"/>
    <label for="session_email">Email</label>
    <input class="form-control" type="email" name="session[email]"
           id="session_email"/>
    <label for="session_password">Password</label>
    <input class="form-control" type="password" name="session[password]"
           id="session_password"/>
    <input type="submit" name="commit" value="Log in" class="btn btn-primary"
           data-disable-with="Log in"/>
</form>

該当するソースコード

<%= form_with(url: login_path, scope: :session) do |f| %>
<form action="/login" accept-charset="UTF-8" method="post">
0

1Answer

form_with は、method: オプション引数でメソッドを指定しなければ、デフォルトで POST を使うからです(もしルーティングに POST がなかったとしても)。

デフォルト値が POST の理由は、 HTML フォームはほとんどの場合 POST で送るのが適切だからです。 HTML フォームは GET または POST で送ることができます1が、 GET で送るとリクエストパラメータが URL に含まれるため、リロードするたびにデータが送信されることになります。これはメールフォームなどの場合では適切ではありません。よって GET は重複したデータを何度送っても問題ない(「副作用がない」)ごく限られた用途に使われます。参考:

  1. Rails の form_with では DELETE や PATCH も使えますが、これは Rails 独自の対応で、フォームに特別なパラメータを含めて HTTP の POST で送ることで実現しています。

2Like

Your answer might help someone💌