一个ruby on rails项目,用户和公司的模型都有地址。

我要创建一个地址表,包含用户和公司表的引用,比直接做下去要好一点,这回让我的数据库设计保持干净。

我的第一印象是,这似乎很难实现,外面所有的讨论及教程都只说明了在model如何设置,但是并没有说明在controller和view如何使用它。我好一顿放狗,也没有得到太多的帮助。

令我感到惊喜是其实在rails设置并使用多态表单是很简单的。

首先依然是先设置model结构:

01 class Company< ActiveRecord::Base
02   has_one :address, :as =>; :addressable, :dependent => :destroy
03 end
04  
05 class User < ActiveRecord::Base
06   has_one :address, :as => :addressable, :dependent => :destroy
07 end
08  
09 class Address < ActiveRecord::Base
10   belongs_to :addressable, :polymorphic => true
11 end

接下来是创建一个Address表来保存地址:

01 class CreateAddresses < ActiveRecord::Migration
02   def self.up
03     create_table :addresses do |t|
04       t.string :street_address1, :null => false
05       t.string :street_address2
06       t.string :city, :null => false
07       t.string :region, :null => false
08       t.string :postcode, :null => false, :limit => 55
09       t.integer :addressable_id, :null => false
10       t.string :addressable_type, :null => false
11  
12       t.timestamps
13     end
14   end
15  
16   def self.down
17     drop_table :addresses
18   end
19 end

接下来是controller,你只需要修改controller中的"new","create","edit","update"四个action,好让需要的时候可以访问和修改address。

01 class CompaniesController < ApplicationController
02  
03   def new
04     @company = Company.new
05     @company.address = Address.new
06   end
07  
08   def edit
09     @company = Company.find(params[:id])
10     @company.address = Address.new unless @company.address != nil
11   end
12  
13   def create
14     @company = Company.new(params[:company])
15     @company.address = Address.new(params[:address])
16  
17     if @company.save
18       @company.address.save
19       flash[:notice] = 'Company was successfully created.'
20       redirect_to(@company)
21     else
22       render :action => 'new'
23     end
24   end
25  
26   def update
27     @company = Company.find(params[:id])
28  
29     if @company.update_attributes(params[:company])
30       @company.address.update_attributes(params[:address])
31       flash[:notice] = 'Company was successfully updated.'
32       redirect_to(@company)
33     else
34       render :action => 'edit'
35     end
36   end
37 end

最后一件事是让address在表单中可以正常工作,我们这里使用field_for方法:

01 <% form_for(@company) do |f| %>
02     <%= f.error_messages %>
03 <dl>
04         <%= f.text_field :name %>
05         <%= f.text_field :telephone %>
06         <%= f.text_field :fax %>
07         <%= f.text_field :website_url %>
08     </dl>
09  
10     <% fields_for(@company.address) do |address_fields| %>
11         <%= address_fields.hidden_field :addressable_id %>
12         <%= address_fields.hidden_field :addressable_type %>
13 <dl>
14             <%= address_fields.text_field :street_address1 %>
15             <%= address_fields.text_field :street_address2 %>
16             <%= address_fields.text_field :city %>
17             <%= address_fields.text_field :region %>
18             <%= address_fields.text_field :postcode %>
19         </dl>
20  
21     <% end %>
22 <% end %>

到这就应该可以正常工作了。

有人要问了,如果我去的了address对象,能否反向取得Company或者User对象呢?答案当然是肯定的。

1 @address = Address.find(params[:id])
2 @address.addressable
3 这样就可以访问了。

Polymorphic form--多态表单的更多相关文章

  1. 解析:使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象

    之前开发时遇到的一个问题,使用easyui的form提交表单,在Chrome下时没问题的,但是在IE下出现类似附件下载时提示是否保存的现象. 这里记录一下如何解决的.其实这个现象不光是easyui的f ...

  2. 阻止form空表单提交----JavaScript

    网上看到很不错的阻止form空表单提交 第一种方法 <div class="warp"> <h2>登录到pfan空间</h2> <p> ...

  3. form注册表单圆角 demo

    form注册表单圆角 <BODY> <div class="form"> <ul class="list"> <li& ...

  4. Form提交表单页面不跳转

    1.设计源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  5. 使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象

    之前开发时遇到的一个问题,使用easyui的form提交表单,在Chrome下时没问题的,但是在IE下出现类似附件下载时提示是否保存的现象. 这里记录一下如何解决的.其实这个现象不光是easyui的f ...

  6. WP Mail SMTP插件解决Contact Form 7表单提交失败问题

    WP Mail SMTP插件解决Contact Form 7表单提交失败问题 WP Mail SMTP是一款非常优秀的解决WordPress主机因为不支持或者是禁用了mail()函数,导致无法实现在线 ...

  7. 关于form与表单提交操作的一切

    原文链接:http://caibaojian.com/form.html 你知道,一个表单里面只要有form元素,如果没有给action加一个默认值,为空白的时候,当你刷新页面时,会弹出一个警告框提示 ...

  8. 【转】document.form.action,表单分向提交

    document.form.action,表单分向提交,javascript提交表单 同一个表单可以根据用户的选择,提交给不同的后台处理程序.即,表单的分向提交.如,在编写论坛程序时,如果我们希望实现 ...

  9. js jquery, jquery-ui 获取form各种表单input的值?

    如何获取? make up (for): 弥补, 补偿, her beaty cannot make up for her stu'pidity. five Basic laws of human s ...

随机推荐

  1. delphi自带的SHA1算法

    delphi自带的SHA1算法 uses IdHashSHA, IdGlobal; function SHA1(Input: String): String; begin with TIdHashSH ...

  2. Android-AndroidStudio莫名其妙的错误-finished with non-zero exit value 1

    上一篇博客,Android-AndroidStudio莫名其妙的错误-finished with non-zero exit value 1,解决了由于 string.xml 字符导致的: 而这篇博客 ...

  3. Checkpoint--相关问题

    Checkpoint是实例级别还是数据库级别? 答:数据库级别,在SQL Server关闭时,会对所有数据库逐一提交checkpoint 测试代码 USE DB0002 GO CHECKPOINT G ...

  4. ajax方式上传图片到Django后台

    参考价值最大 https://blog.csdn.net/huangql517/article/details/81259671 https://www.cnblogs.com/chenjianhon ...

  5. 什么是Ajax?Ajax的原理是什么?Ajax的核心技术是什么?Ajax的优缺点是什么?

    Ajax是一种无需重新加载整个网页,能够更新部分网页的技术.Asynchronous JavaScript and XML的缩写,是JavaScript.XML.CSS.DOM等多个技术的组合. Aj ...

  6. Python小白学习之路(八)—【变量】【基本数据类型分类】【集合】【集合的功能】

    一.变量 变量的作用:记录状态的变化变量的值:描述不同的状态 二.五大基本数据类型的分类 五大基本数据类型(数字 字符串 列表 元祖 字典) 按照可变不可变来进行分类 可变:列表.字典 不可变:字符串 ...

  7. iOS-消除CocoaPods内容警告

    前言 2018年2月26日 农历正月十一 星期一 今天就想更新下博客,内容不多,心情复杂: 突然想吟诗一首: 其实,我是一个善良的人: 其实,我是一枚... 算了,还是说正事吧 消除CocoaPods ...

  8. 解决ORA-21561: OID generation failed

    解决ORA-21561 在linux上使用sqlplus连接oracle数据库 [root@china ~]# sqlplus test/test@ORCL SQL Production :: Cop ...

  9. FineReport9.0定义数据连接(创建与SQL Server 2016数据库的连接)

    1.下载并安装好FineReport9.0和SQL Server 2016 2.开始——>所有应用——>Microsoft SQL Server 2016——>SQL Server ...

  10. jQuery过滤选择器:first和:first-child的区别,CSS伪类:first-child

    最近项目中遇到需求:只在第一列不能删除,不显示小叉号:点击可添加一列,后面的列右上角显示小叉号,可以点击删除. 我是使用以下方法解决这个小需求 :CSS伪类选择器:first-child设置所有小叉号 ...