一个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. Python学习-38.Python中的正则表达式(二)

    在Python中,正则表达式还有较其他编程语言有特色的地方.那就是支持松散正则表达式了. 在某些情况,正则表达式会写得十分的长,这时候,维护就成问题了.而松散正则表达式就是解决这一问题的办法. 用上一 ...

  2. Elasticsearch 的一些关键概念

    我更喜欢把 Elasticsearch 作为一种 nosql 去理解,它的一些开发概念和 MongoDB 以及 Redis 没有太大的区别,不过了解 Elasticsearch 中的一些核心概念对于你 ...

  3. jquery批量控制表单元素

    网上查了很久,避免下次再遇到相同的问题,记录一下: $("form input").prop("readonly", true); $("form i ...

  4. (C#)冒泡排序

    //冒泡排序 public static int[] Bubbling(int[] s) { int a; for (int i = 0; i < s.Length-1; i++) { for ...

  5. WPF 改变Datagrid的选中行的颜色

    主要通过设置DataGrid的RowStyle和CellStyle即可. <Style TargetType="DataGridRow" x:Key="gridRo ...

  6. neutron openvswitch + vxlan 通讯

  7. Android与js交互

    本文转载自:http://blog.csdn.net/it1039871366/article/details/46372207 一文. Android 中可以通过webview来实现和js的交互,在 ...

  8. git 拖下laravel 代码后报错 Warning: require(D:\WWW\laravel\bootstrap/../vendor/autoload.php

    omposer    install  执行 Problem 1    - Installation request for doctrine/annotations v1.5.0 -> sat ...

  9. Python拾遗

    for...else...语句 用 break 关键字终止当前循环就不会执行当前的 else 语句,而使用 continue 关键字快速进入下一论循环,或者没有使用其他关键字,循环的正常结束后,就会触 ...

  10. ZZNU 2055(基姆拉尔森计算公式)

    题目链接 题意: 比如今天是2017年8月16日,星期三.下一个也是星期三的8月16日发生在2023年. 现在是日期是yyyy-mm-dd,我们希望你求出薛定谔会跳跃到那一年. 题解: emmmm.. ...