使用FORM同时更新多条记录的研究

1 view
Skip to first unread message

大师傅

unread,
Sep 4, 2007, 4:14:42 AM9/4/07
to rails4scm
我们看到tapestry或者jsf能以多行编辑方式同时更新一个表的多条记录,感觉这两个框架很牛,其实这是 HTML form 的基本功能,原理
也不复杂:
只要我们设法使得form中各个text_field 的 name属性成为:
items['2']['code']
items['2']['name']
items['2']['remark']
items['10021']['code']
items['10021']['name']
items['10021']['remark']

那么,当form 执行post时,URL的params属性就成了
params= {"items"=>{"2"=>{"name"=>"名", "code"=>"码", "remark"=>"注"},
"10021"=>{"name"=>"新", "code"=>"new", "remark"=>"信
息也是新"}}, "commit"=>"Update All Items"}

因此只要在 controller 中写如下代码就可以同时更新这三条记录:
def update
for record in params[:items]
item=Item.find(record[0])
item.update_attribut(record[1][code])
item.update_attribut(record[1][name])
item.update_attribut(record[1][remark])
end
# 错误处理略
end

说明,这里是ruby代码。由于params的items数组,其元素record是HASH键值对,因此in操作使得可简单地用[0]取其
key [1]取得其值。 不信用下面短句在irb中测试一下:
h = {1 => 2, "2" => "4"}
h.each {|a| p a}
再有,实际程序的的rhtml模版文件内容如下:
<% form_tag :action => :update do %>
<table>
<tr>
<% for column in Item.content_columns %>
<th><%= column.human_name %></th>
<% end %>
</tr>
<% i=0 %>
<% for item in @items %>
<tr>
<% for column in Item.content_columns %>
<td>
<%=tag("input", { :type => :text,
:id=>"item_#{i}_#{column.name}",
:name=> "items["+ @items[i].id.to_i.to_s+"]
[#{column.name}]",
:value=>@items[i].attributes["#{column.name}"]
}) %>
</td>
<% end %>
</tr>
<% i+=1 %>
<% end %>
</table>
<br />
<%= submit_tag 'Update All Items' %>
<% end %>

由于通用编程, 相应的control代码也没有写死列名:
def update
i=0
for record in params[:items]
item=Item.find(record[0])
if not item.update_attributes(record[1]) then i+=1 end
end
if i==0 then
flash[:notice] = 'Item was successfully updated.'
redirect_to :action => 'list'
else
flash[:notice] = 'Item updated failed!'
render_text "reocords update failed"
end
end

瞧,是不是不复杂。 当然了,调试通过还是很费神的 :(

Reply all
Reply to author
Forward
0 new messages