同一个表单提交一对多关联的多个Model

最近做了一个小项目.在项目中有一个提交产品,产品有一个信息介绍..产品与介绍是一对多的关系..在添加产品的时候要进行同一表单提交多个Model..查看了一些资料,实现的方法如下.
首先来看看数据库和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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值