浏览 5988 次
锁定老帖子 主题:同一个表单提交一对多关联的多个Model
精华帖 (0) :: 良好帖 (7) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-06
首先来看看数据库和Model的 数据库脚本迁移文件 class CreateProductInfos < ActiveRecord::Migration def self.up create_table :product_infos do |t| t.string :title,:limit=>100,:null=>false t.string :content,:null=>false #对应的产品 t.integer :product_id t.timestamps end end def self.down drop_table :product_infos end end class CreateProducts < ActiveRecord::Migration def self.up create_table :products do |t| t.string :name, :limit => 100, :null => false t.text :remark, :null => true t.string :img_path t.timestamps end end def self.down drop_table :products end end 在Model部分..添加上关联. class ProductInfo < ActiveRecord::Base belongs_to :product end class Product < ActiveRecord::Base has_many :product_infos end View设计,View部分主要部分注意, <%= link_to_remote "添加产品信息" , :update => "product_types",:url => { :action => "add_product_type" },:position => 'bottom' %> 使用Ajax方式请求服务器.返回的数据更新倒product_types元素上..这个元素就是一个td..代码在最下边贴吧.. controller很简单,就是返回一个模板,主要的目的是动态的添加信息 def add_product_type render :partial => "product_type" end product_type很简单,就是两个产品信息的文本框 <p> <%=text_field_tag "product_infos[][title]","",:size=>20%> <%=text_field_tag "product_infos[][content]","",:size=>40%> </p> 写到这里就实现了一个动态添加一个商品信息的页面..当用户点击"添加产品信息"按钮的时候,就会在页面上增加两个文本框,点一次多一个,点一次多一个!!很简单吧~~嘿嘿 然后就是controller上save方法了..我们在页面上添加了一个product_infos[],那么controller上通过params[:product_infos]取出商品信息,然后添加倒商品上.保存到数据库就OK啦. Controller的设计 def save #获取所有商品的类型. @product_types = ProductType.find :all if request.post? #使用表单数据创建一个商品对象 @product = Product.new params[:product] #迭代页面传递来的所有产品信息 params[:product_infos].each do |info| #根据信息创建一个信息实体 product_info = ProductInfo.new info #如果产品信息的标题存在, if product_info.title.size > 0 将产品信息和产品关联上 @product.product_infos << product_info end end #保存产品 if @product.save #如果存在图片,那么上传图片,更新商品信息 img_path = add_file @product.img if @product.img.size > 0 if img_path @product.update_attributes(:img_path => "/uploads/"+img_path) end goto_index "保存成功" end end end 这个是完整的View页面... <%form_tag ({:action=>:save},:multipart =>true) do%> <table width="100%"> <tr> <td width="50px">产品名:</td> <td> <%=collection_select "product","product_type_id",@product_types,"id","name"%> </td> </tr> <tr> <td>标题:</td> <td><%=text_field "product","name"%></td> </tr> <tr> <td colspan="2"> <%=file_field "product","img"%> </td> </tr> <tr> <td colspan="2"> <%= fckeditor_textarea("product", "remark", { :toolbarKit => 'Simple', :width => '95%', :height => '350px' }) %> </td> </tr> <tr> <td colspan="2"> <table width="100%"> <tr> <td width="150px">信息标题</td> <td>信息内容</td> </tr> <tr> <td colspan="2" id="product_types"> <%render :partial => "product_type"%> </td> </tr> </table> </td> </tr> <tr> <td colspan="2"> <%= link_to_remote "添加产品信息" , :update => "product_types",:url => { :action => "add_product_type" },:position => 'bottom' %> </td> </tr> <tr> <td colspan="2"> <%= submit_tag "保存" %> </td> </tr> </table> <%end%> 修改view和save.rhtml是一样的..只不过多了一个循环,先把数据库中已有的信息显示出来. <%for info in @product.product_infos%> <p> <%=text_field_tag "product_infos[][title]",info.title,:size=>20%> <%=text_field_tag "product_infos[][content]",info.content,:size=>40%> </p> <%end%> 更新部分的Collector和save的稍有不同.我使用update_attributes更新数据库,那么就要把infos添加到params[:product]中.应该实现params[:product][:product_infos] = Array.new 在Array.new中是一个一个的ProductInfo.new 代码如下 def update @product_types = ProductType.find :all @product = Product.find params[:id] if request.post? #创建一个新的元素 params[:product][:product_infos] = Array.new #迭代页面提交上来infos params[:product_infos].each do |info| #创建ProductInfo实体 product_info = ProductInfo.new info #如果ProductInfo实体的标题有效 if product_info.title.size > 0 #将ProductInfo添加到hash中 params[:product][:product_infos] << product_info end end #根据hash更新商品 if @product.update_attributes params[:product] img_path = add_file @product.img if @product.img.size > 0 if img_path @product.update_attributes(:img_path => "/uploads/"+img_path) end goto_index "修改成功" end end end 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-06
在上传图片部分对sql执行了两次,先添加,后更新.感觉不太好..但是对上传不太了解..好像只有在执行了save或者update以后才会生成这个img对象.有没有更好的上传解决方案呢?
|
|
返回顶楼 | |
发表时间:2008-07-09
我觉得你把增加一行产品的信息收集表单,用javascript来实现更方便一点。
|
|
返回顶楼 | |
发表时间:2008-07-09
以前也有一个项目是用js实现的(java项目),但是在后期发现,因为很多js代码的存在,页面后期很难维护.
而且从性能上来将,一个静态页面请求并不会给服务器多大负担,我感觉还是这种ajax方式来处理方便. |
|
返回顶楼 | |
发表时间:2008-07-10
看看这个http://railscasts.com/episodes/75
|
|
返回顶楼 | |
发表时间:2008-07-11
严重同意studyworks。我看到这篇的标题马上就想到了complex form的三个rais casts。从part 1看起会更容易理解一些。
|
|
返回顶楼 | |
发表时间:2008-07-11
刚刚看了一下.确实不一样哦..嘿嘿!!看来水平还不够,继续努力!
|
|
返回顶楼 | |