ก็เลยพึ่งเห็นวิธีที่ rails ใช้จัดการกับวันที่
ใน rhtml template เราสามารถใช้ date_select
ช่วยการ render date widget ได้
หน้าตาที่ได้ ก็จะเป็น dropdown box แบบนี้
เมื่อเกิด form submit
ข้อมูลที่ post กลับมาจะอยู่ในรูปแบบนี้
{
"start_date(1i)"=>"2006",
"start_date(2i)"=>"1",
"start_date(3i)"=>"1"
}
สังเกตว่า มีวงเล็บ แปลกๆอยู่ด้วย
เมื่อ controller ได้รับข้อมูลกลับมา
ก็จะทำการ assign ให้กับ model
ซึ่งเราสามารถใช้คำสั่งแบบนี้ได้
mymodel.attributes = params[:mydate]
mymodel.save
หรือจะใช้
mymodel.update_attributes(params[:mydate])
ทั้งสองวิธีทำงานเหมือนกัน (วิธีที่ 2 code ข้างใน ก็ไปเรียกแบบที่ 1)
ประโยค
mymodel.attributes = ...
ไม่ได้เป็นการ assigment แบบธรรมดา
ภายใน ActiveRecord มีการ declare method นี้ไว้ดังนี้
def attributes=(attributes)
return if attributes.nil?
attributes.stringify_keys!
multi_parameter_attributes = []
remove_attributes_protected_from_mass_assignment(attributes).each do |k, v|
k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v)
end
assign_multiparameter_attributes(multi_parameter_attributes)
end
การทำงานก็คือ แต่ละ attribute ที่ pass เข้ามา
กรณีที่เป็น attribute แบบไม่มีเครื่องหมาย
(
ก็จะถูกเรียกใช้แบบนี้
send(k+"=", v)
สมมติ attribute เป็น
"name" => "pphetra"
ประโยค
send(k+"=", v)
ก็คือ send("name=", "pphetra)
ซึ่งเทียบได้กับ
name = "pphetra"
แต่กรณีที่มันพบ attribute ที่มีเครืื่องหมาย "
(
"กรณีนี้จะถูก handle แบบพิเศษโดยใช้ assign_multiparameter_attributes
ซึ่งถ้าดูใน document ของ method นี้ เขาอธิบายการทำงานดังนี้
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float,
# s for String, and a for Array. If all the values for a given attribute is empty, the attribute will be set to nil.
No comments:
Post a Comment