Signup form HTML

這節來瞭解一下 form_for 的構成。

form_for 是由 ERb 調用該方法,結尾是 end

<%= form_for(@user) do |f| %>
  .
  .
  .
<% end %>

do 關鍵字指出 form_for 接受一個 block 帶著一個參數 ff 的作用就是產生相對應的 HTML 元素,例如:

<%= f.label :name %>
<%= f.text_field :name %>

這兩行會產生 @user 物件的 label tag、input。

如果查看 HTML 原始碼的話會長這樣:

<form accept-charset="UTF-8" action="/users" class="new_user"
      id="new_user" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden"
         value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />
  <label for="user_name">Name</label>
  <input id="user_name" name="user[name]" type="text" />

  <label for="user_email">Email</label>
  <input id="user_email" name="user[email]" type="email" />

  <label for="user_password">Password</label>
  <input id="user_password" name="user[password]"
         type="password" />

  <label for="user_password_confirmation">Confirmation</label>
  <input id="user_password_confirmation"
         name="user[password_confirmation]" type="password" />

  <input class="btn btn-primary" name="commit" type="submit"
         value="Create my account" />
</form>

所以剛剛的:

<%= f.label :name %>
<%= f.text_field :name %>

最後會被輸出成:

<label for="user_name">Name</label>
<input id="user_name" name="user[name]" type="text" />

之後會講到,之所以可以建立使用者,是因為 input 的 name 屬性:

<input id="user_name" name="user[name]" - - - />
.
.
.
<input id="user_password" name="user[password]" - - - />

Rails 以這些 name 的屬性值作為 key,而使用者輸入的資料為 value,建構出一個叫 params 的 hash,用來建立使用者。

Rails 使用 @user 物件建立 form tag,因為 Ruby 物件會知道自己屬於哪一個 class,所以 Rails 知道 @user 的 class 是 User。此外,因為 @user 是一個新的使用者,所以 Rails 知道在 form 上使用 post 方法,這正是建立新物件所需要的 HTTP 請求:

<form action="/users" class="new_user" id="new_user" method="post">

上面的 action="/users"method="post",會讓 Rails 向 /users 發送 POST 請求。

form tag 下面還會有這段程式碼:

<div style="display:none">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden"
         value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />
</div>

這段程式碼不會顯示在瀏覽器中,只對 Rails 內部有用。它使用 Unicode 字串 &#x2713; (a checkmark ✓)強制瀏覽器使用正確的字串編碼提交資料。authenticity token 是 Rails 用來防禦 Cross-Site Request Forgery,簡稱 CSRF。