`
superxielei
  • 浏览: 266573 次
  • 性别: 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,用于将多个表单组合到一起。 示例代码 以下是一个简单的示例代码,...

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

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

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

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

    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_...

    提交信息生成个人简历

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

    ssh(struts、spring、hibernate)面试题

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

    hibernate_formToModelConvertor

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

    代码和关联文件

    标题中的“代码和关联文件”指的是一个压缩包中包含了多种编程语言的代码文件以及可能的关联库或依赖。在这个场景下,我们有三个文件:C#.txt、php.txt和php5tsdll。这些文件分别代表了C#和PHP这两种编程语言的代码...

    django中如何使用admin进行多个模型的后台管理

    如果模型之间存在一对一或一对多关系,Django Admin可以展示嵌套的数据。例如,`Book`模型与`Author`模型是一对一关系,我们可以在`Book`的Admin中直接编辑`Author`的信息: ```python class BookAdmin(admin....

Global site tag (gtag.js) - Google Analytics