我們之前的例子都用了html原生的表單,書寫起來字?jǐn)?shù)較多币励,而且缺少驗(yàn)證機(jī)制阳仔。在rails中提供了更加方便的,安全的表單怯疤。
我們在/myclasses/edit.html.erb中寫入兩個表單浆洗,一個是html的form,另一個是rails中的form_for集峦,如下:
<h1>修改班級</h1>
<form action='/myclasses/<%=params[:id]%>' method=POST>
<input type='hidden' name='_method' value='put'>
班級名稱:<input type='text' name='name'><br>
班級描述: <input type='text' name='description'><br>
<input type='submit' value='提交'>
</form>
<%= form_for @myclass do |f| %>
班級名稱:<%= f.text_field :name %><br>
班級描述:<%= f.text_field :description %><br>
<%= f.submit "提交"%>
<% end %>
一伏社、參數(shù)的傳遞
可以看到form_for的代碼簡介不少,這段代碼到底生成了什么組件呢塔淤,我們可以到瀏覽器中用檢查功能查看摘昌。如下:
可以看到里面生成了以下東西:
class,
id高蜂,
action(路徑)聪黎,
accept-chaset(字體)隱藏,
method(提交方式)隱藏,
anthenticity_token(驗(yàn)證機(jī)制)里面的數(shù)字是機(jī)器自動生成的备恤,提高了安全性稿饰,
name字段,
description字段烘跺,
submit提交按鈕湘纵。
那么我們我們新建了一個班級,name是“class123123”滤淳,description是“一級”梧喷,在update方法中打上斷點(diǎn),看后臺獲得了什么。如下:
整理后如下:
{
"utf8"=>"?",
"_method"=>"patch",
"authenticity_token"=>"UvQrcnbzosn0+fWiqs/cYqIPg1Vd3ygjRK2nbj7Qe2AlsgW+nGco0oqfXOrJ3T0sgMPA4asf9cDkS/ZW2zA//w==",
"myclass"=>{
"name"=>"class123123",
"description"=>"一級"
},
"commit"=>"提交",
"controller"=>"myclasses",
"action"=>"update",
"id"=>"3"
}
可以清晰的看到全部對應(yīng)上了铺敌,這些都是前臺頁面?zhèn)鬟f過來的汇歹。
這里我們用params方法,就可以獲得我們要的參數(shù)偿凭,然后寫入controller的update产弹。
二、form表單的問題和form_for表單的優(yōu)點(diǎn)
form表單的問題:不方便
例子:我們新建一個班級弯囊,其中name為abc痰哨,description為123,在后臺用params方法可以獲取的數(shù)據(jù)為:
{
"_method"=>"put",
"name"=>"abc",
"description"=>"123",
"controller"=>"myclasses",
"action"=>"update",
"id"=>"3"
}
這里匾嘱,最重要的參數(shù)就是輸入框輸入的name和description參數(shù)斤斧,我們需要把它們和其他method、action等不需要我們后續(xù)操作的參數(shù)進(jìn)行分離霎烙。那么撬讽,我們可以用params[:name]和params[:description]就能得到abc和123。
但是問題來了:因?yàn)檫@些都是孤立的參數(shù)悬垃,我們必須挨個獲取游昼。如果里面字段不止兩條,而是有幾十條尝蠕,那么我們的controller中就要用params獲取幾十次的參數(shù)烘豌,非常麻煩。
這里就要引入一個表單對象的概念趟佃,我們只要提取表單里面的對象扇谣,就可以獲得對象所有的屬性,如此例子中的myclass就是對象闲昭,name和description就是屬性透敌。我們要改為myclass[:name]和myclass[:description]找都,這樣就好了明刷。通過params[:myclass]就可以獲得name和description了启绰。當(dāng)然,這在form_for中是封裝好的簸淀,用就是了瓶蝴。
form_for的優(yōu)點(diǎn)
還是之前的例子:myclass輸入兩個字段:name為class123123,description為一級租幕。
{
"utf8"=>"?",
"_method"=>"patch",
"authenticity_token"=>"UvQrcnbzosn0+fWiqs/cYqIPg1Vd3ygjRK2nbj7Qe2AlsgW+nGco0oqfXOrJ3T0sgMPA4asf9cDkS/ZW2zA//w==",
"myclass"=>{
"name"=>"class123123",
"description"=>"一級"
},
"commit"=>"提交",
"controller"=>"myclasses",
"action"=>"update",
"id"=>"3"
}
后臺我們只要用params[:myclass]舷手,就能把name和description等需要處理的參數(shù)拿到,即使有一百個參數(shù)劲绪,也只需一次操作:
{
"name"=>"class123123",
"description"=>"一級"
}
三男窟、初步拆解各部件
<%= form_for @myclass do |f| %>
班級名稱:<%= f.text_field :name %><br>
班級描述:<%= f.text_field :description %><br>
<%= f.submit "提交"%>
<% end %>
這個表單中盆赤,
實(shí)例@myclass就是這個表單的對象。
“f”是表單中的常用寫法歉眷,可以寫成任意字符牺六,它代表@myclass,作為局部變量被之后的操作調(diào)用汗捡。
text_field淑际,簡單理解,能生成一個輸入框扇住,并且是text格式春缕。
submit是按鈕功能,后面的“提交”是按鈕的名字艘蹋,可自定義淡溯。
四、form_for使用的注意事項(xiàng)
1)在新建實(shí)例的時候簿训,配合controller#new方法使用,在#new中需要定義好相關(guān)操作米间;
2)在更新實(shí)例的時候强品,配合controller#update方法使用,需要在#update中做好操作屈糊;
3)在 controller中的榛,要配合健壯參數(shù)private使用,如:
private
def myclass_params
params.require(:myclass).permit!
end
permit加感嘆號就能獲取:myclass中的所有參數(shù)逻锐,但是最好把參數(shù)挨個寫全夫晌,減少安全問題。
如果只要其中的幾個昧诱,可以接小括號晓淀,里面放具體參數(shù)。也可以接except盏档,排除里面的某幾個參數(shù)凶掰。