`
superxielei
  • 浏览: 267204 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

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

    博客分类:
  • ROR
阅读更多
最近做了一个小项目.在项目中有一个提交产品,产品有一个信息介绍..产品与介绍是一对多的关系..在添加产品的时候要进行同一表单提交多个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
分享到:
评论
6 楼 superxielei 2008-07-11  
刚刚看了一下.确实不一样哦..嘿嘿!!看来水平还不够,继续努力!
5 楼 ashchan 2008-07-11  
严重同意studyworks。我看到这篇的标题马上就想到了complex form的三个rais casts。从part 1看起会更容易理解一些。
4 楼 studyworks 2008-07-10  
看看这个http://railscasts.com/episodes/75
3 楼 superxielei 2008-07-09  
以前也有一个项目是用js实现的(java项目),但是在后期发现,因为很多js代码的存在,页面后期很难维护.
而且从性能上来将,一个静态页面请求并不会给服务器多大负担,我感觉还是这种ajax方式来处理方便.
2 楼 taito 2008-07-09  
我觉得你把增加一行产品的信息收集表单,用javascript来实现更方便一点。
1 楼 superxielei 2008-07-06  
在上传图片部分对sql执行了两次,先添加,后更新.感觉不太好..但是对上传不太了解..好像只有在执行了save或者update以后才会生成这个img对象.有没有更好的上传解决方案呢?

相关推荐

    Spring MVC3复杂表单终极解决办法

    复杂表单通常涉及到多个关联对象的提交,比如用户信息与地址信息在一个表单中同时提交,或者订单与订单详情的关联数据。在Spring MVC中,这种复杂性可以通过模型绑定(Model Binding)和数据转换(Data Conversion)...

    django中ModelForm多表单组合的解决方案.docx

    在某些情况下,我们需要将多个表单组合到一个表单中。这时候,我们可以使用 Django 的 FormSet 来实现多表单组合。FormSet 是一种特殊的 Form,用于将多个表单组合到一起。 示例代码 以下是一个简单的示例代码,...

    JAVA动态表单设计,自定义表单,自定义数据

    这种技术的核心在于提供一个灵活的、可配置的平台,用户或开发者可以通过界面来定义表单字段、布局以及与后端数据的交互方式。以下是对这个主题的详细讲解: 1. **动态表单的概念** 动态表单是指可以在运行时根据...

    hibernate+struts一对多增删改查demo(学生对班级)

    在Hibernate中,我们可以通过在实体类中定义集合属性(如List或Set)来表示这种关系,同时在对应的.hbm.xml映射文件中配置一对多的关联。 2. **数据库设计**:MySQL数据库中会有两个表,一个是`student`,包含学生...

    Web表单高级技巧

    "Web表单高级技巧"这一主题涵盖了提高用户体验、数据验证、表单处理和交互性等多个方面。接下来,我们将深入探讨这些高级技巧。 首先,我们关注表单设计。一个优秀的Web表单应该直观易用,减少用户的认知负担。这...

    表单数据自动封装到javaBean中

    总结,表单数据自动封装到JavaBean涉及到多个层面的技术,包括Web框架的特性利用、数据验证、错误处理以及自定义逻辑。理解并熟练掌握这些技术,能极大地提高开发效率和代码质量。在实际项目中,可以根据需求选择...

    表单组件使用learn; 

    10. **form(表单)**:包含多个表单组件,用于封装表单的提交、验证等功能。 三、表单组件的属性与事件 每个组件都有各自的属性和事件,例如`input`组件的`value`属性用于获取或设置输入的文本,`@input`事件则...

    43-Hibernate数据关联实现〖MVSN〗_Struts + DAO + Hibernate(6).rar

    例如,一个用户可以有多个订单,这是一种一对多的关系;反之,每个订单对应一个用户,这是一种多对一的关系。实现数据关联通常通过配置XML映射文件或使用注解来完成。 **Struts框架**:Struts是基于MVC设计模式的...

    Vue循环中多个input绑定指定v-model实例

    然而,当需要在循环中创建多个表单元素,如`input`,并希望每个输入框都有自己的独立绑定时,就需要采取特定策略。下面将详细介绍在循环中为多个`input`绑定指定`v-model`实例的两种方法。 ### 方法一:`v-for`循环...

    Odoo10开发之模型关联-中文

    - **应用场景**: 销售订单与客户之间的一对多关系,其中销售订单属于Many2one的一端,客户则处于一端。在本案例中,我们可以设想一个`Session`关联到一个具体的`Course`。 - **示例代码**: ```python course = ...

    解决django中ModelForm多表单组合的问题

    然而,当需要在一个视图中处理多个相关联的表单时,问题就出现了。如何优雅地组合多个ModelForm来处理多张数据库表的数据呢?这篇文章将探讨如何解决这一问题。 首先,我们需要了解Django的基础表单——Form。Form...

    vue.js使用v-model实现表单元素(input) 双向数据绑定功能示例

    在Web开发中,数据的双向绑定是一种非常实用的技术,它可以将用户界面(UI)与数据状态紧密地关联起来,使得数据模型的任何变动都能即时反映到视图上,同样用户对视图的操作也可以实时地更新数据模型。在前端框架Vue....

    vue 表单之通过v-model绑定单选按钮radio

    在Vue.js框架中,表单元素的双向数据绑定是一个强大的特性,它简化了与用户交互时的数据管理。本文将深入探讨如何使用`v-model`指令来绑定Vue中的单选按钮(radio),以便实现更加高效和简洁的代码编写。 ### 一、...

    hibernate_formToModelConvertorOneToMany.rar

    本资料主要围绕“Hibernate Form到Model转换器在处理一对多关系映射”这一主题进行深入探讨,通过实例解析如何实现从表单数据到模型对象的高效转换,并处理一对多关联关系。 首先,让我们理解什么是Form到Model转换...

    django多文件上传,form提交,多对多外键保存的实例

    此外,由于一个反馈可能包含多个图片,所以我们定义了一个多对多关系`images`,它关联到另一个模型`UserFeedbackImages`。 ```python class UserFeedback(models.Model): user = models.ForeignKey(User, verbose_...

    Dorado7实现部门以及部门下员工信息增删改

    这些字段可以通过外键关联,形成部门和员工的一对多关系。 在Dorado7中,我们通常会创建一个数据模型(Model)来表示数据库中的表,这样可以方便地进行数据操作。对于部门和员工信息,我们可以定义两个数据模型,...

    提交信息生成个人简历

    总结起来,"提交信息生成个人简历"这一任务涉及到.NET MVC的多个核心概念,包括模型绑定、控制器操作、视图渲染以及数据验证等,这些都是Web开发中不可或缺的技能。通过这个简单的实例,初学者可以了解到如何构建一...

    ssh(struts、spring、hibernate)面试题

    1. 避免单向一对多,使用双向一对多关联。 2. 恰当地使用单向一对多关联。 3. 尽量用多对一替代一对一。 4. 配置对象缓存,避免集合缓存。 5. 一对多集合使用Bag,多对多集合使用Set。 6. 使用显式多态处理继承类。 ...

    hibernate_formToModelConvertor

    它支持事务管理、缓存机制、一对多、多对一、一对多等复杂的关联关系映射。 2. 表单数据处理:在Web应用中,用户通常通过表单提交数据。这些数据以键值对的形式存在,例如HTTP请求参数。开发者需要将这些数据转化为...

    Spring+Hibernate+Struts工作原理

    1. 避免使用单向一对多关联,改为双向一对多。 2. 合理使用单向一对多关联。 3. 避免一对一关系,用多对一代替。 4. 配置对象缓存,避免使用集合缓存。 5. 一对多集合使用Bag,多对多集合使用Set。 6. 继承类使用...

Global site tag (gtag.js) - Google Analytics