一个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 中 FindWindow 和 FindWindowEx 的语法和用法

    FindWindow(lpClassName,        {窗口的类名}lpWindowName: PChar {窗口的标题}): HWND;              {返回窗口的句柄; 失败返 ...

  2. DXDBGrid使用方法

    http://www.cnblogs.com/gtsup/archive/2012/08/28/2660197.html dxDBGrid使用集锦   转载自:http://hi.baidu.com/ ...

  3. Postgresql 創建觸發器,刪除觸發器和 禁用觸發器

    CREATE OR REPLACE FUNCTION XF_VIP_AFUPD_WX() RETURNS trigger AS $$ DECLARE i_count integer; s_wx_ope ...

  4. Regex Golf练习笔记(1)

    正则表达式进阶练习:https://alf.nu/RegexGolf  (此练习笔记) 正则表达式验证:https://regexr.com/ (1) (2) 注释:每个词的三个字母在后面重复出现了一 ...

  5. C#使用oledb操作excel文件的方法

    本文实例讲述了C#使用oledb操作excel文件的方法.分享给大家供大家参考.具体分析如下: 不管什么编程语言都会提供操作Excel文件的方式,C#操作Excel主要有以下几种方式: 1.Excel ...

  6. C#图片处理,缩略图制作

    准备参数:图片文件流.文件名 方法:1.先将图片流通过System.Drawing.Image.FromStream方法转成图片对象 2.通过图片对象.GetThumbnailImage方法生成自定义 ...

  7. ASP.NET Core SignalR CORS 跨域问题

    将 SignalR 集成到 ASP.NET Core api 程序的时候,按照官方 DEMO 配置完成,本地访问没有问题,但是发布之后一直报跨域问题,本地是这样设置的: 原始代码: services. ...

  8. sql service 备份

    declare @SqlBackupDataBase as nvarchar(1000)set @SqlBackupDataBase=N'BACKUP DATABASE YSKJ_Wechat TO ...

  9. 机器学习、深度学习、和AI算法可以在网络安全中做什么?

    本文由  网易云发布. 本文作者:Alexander Polyakov,ERPScan的首席技术官和联合创始人.EAS-SEC总裁,SAP网络安全传播者. 现在已经出现了相当多的文章涉及机器学习及其保 ...

  10. WPF MVVM 网易云音乐

    前言: 写的不多. 随时会更新吧 涉及到的技术有很多 绑定 集合 命令 MVVM 自定义控件 事件 用户控件 附加属性 依赖属性 动画 Style Tmepate 装饰器 转换器 ********** ...