form_tag 是啥?跟 form_for 有什麼不一樣?


一般在Rails的app當中,常會看到form_tag的用法,基本上就是為了傳送http的POST request使用,就像我們在瀏覽器中直接輸入網址就可以發出GET request一樣。

form_tag

基本上,一個form_tag會長這樣:

<%= form_tag sessions_path do %>

<% end %>

這樣基本的code就會產生:

<form action="/sessions" method="post">

</form>

簡單來說,我們就是在這樣的表格中送出需要的變數。例如一個登入表格:

<%= form_tag sessions_path do %>
  Name: <%= text_field_tag :username %>
  Password: <%= password_field_tag :password %>
  <%= submit_tag "Submit" %>
<% end %>

這樣的code就會產生兩個欄位以及一個送出按鈕了。

與form_for的差異

一般來說,form_for是為了Rails的ActiveRecord而設,主要用於建立或修改一筆Model的資料,例如我們在controller當中先設定@user = User.new那在view當中就這樣寫:

<%= form_for @user do |user| %>
  <%= user.text_field :name %>
  <%= user.password_field :password %>
  <%= user.submit "Submit" %>
<% end %>

這樣的寫法當中,已經設定好整個表格就是為了@user這個ActiveRecord資料而設定,所以表格送出的params會將我們在表格內填的變數整個包在user物件底下。所以才會需要使用Strong Parameter那樣的機制將user變數抽出:

def user_params
  params.require(:user).permit(:name, :password)
end

如果是使用form_tag,變數就不會包在任何東西內,可以直接在controller當中取用:

def search
  @users = User.where(:name => params[:search])
end

不過form_tag內的物件若要用在ActiveRecord的create或update action上,還是必須經過permit這個method來允許這些變數改動資料庫,這是Rails的一個安全機制。

補充

form_tag就像一般的Rails Helper一樣,都可以在後方加上html選項。

<%= form_tag sessions_path, :method => :put, :class => "my_form" do %>
<% end %>

對於Strong Parameter機制還不熟的朋友,可以參考xdite在部落格上說明的文章

其他參考資料

  1. API Dock: form_for
  2. API Dock: form_tag