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

    作为一门现代语言,正则表达式是必不可缺的,在Python中,正则表达式位于re模块. import re 这里不说正则表达式怎样去匹配,例如\d代表数字,^代表开头(也代表非,例如^a-z则不匹配任何 ...

  2. H2内存数据库支持存储到文件

    准备工作 1.下载JDK(本人下载的版本为JDK1.7).设置环境变量JAVA_HOME,设置PATH(%JAVA_HOME%\bin%). 2.下载并解压:h2-2014-07-13.zip 官网下 ...

  3. Quartz.net 起步

    安装 Quartz 程序包 使用 nuget 命令行安装 Quartz: Install-Package Quartz 如果使用 JSON 序列化,使用 nuget 安装 Quartz.Seriali ...

  4. git archive命令详解

    git archive可以将加了tag的某个版本打包提取出来,例如: git archive -v --format= > v0..zip --format表示打包的格式,如zip,-v表示对应 ...

  5. Jersey构建Restful风格的webservices

    最近一直在搞老项目的开发工作,很少写博文了.听了两位阿里巴巴大牛的讨论,决定试试用restful风格的webservices看看. 这里用的是Jersey这个框架,刚开始弄,有点麻烦,只能到处查资料. ...

  6. .net core获取服务器本地IP及Request访问端口

    string str = (Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" + ...

  7. Android 导入 aar 库文件

    1. 在需要导入 aar 的 module 目录下创建一个名叫 "aars" 的目录,并把 aar 文件复制到这里. 2. 在项目的 build.gradle 文件里添加 allp ...

  8. kolla-ansible 源码下载

    下载地址: https://pypi.org/project/kolla-ansible/ ansible下载: https://releases.ansible.com/ansible/rpm/re ...

  9. Cordova - 彻底搞定安卓中的微信支付插件!

    Cordova:8.0.0 Android studio:3.2.1 cordova-plugin-adam-wechat : 3.0.6 你看到这个标题肯定会惊讶,一个Cordova的微信支付插件, ...

  10. JQuery Mobile - 解决动态更新页面内容,CSS失效问题!

    今天编写JQuery Mobile程序,需要对数组数据动态创建,并且每条数据对应一个复选框,于是我很顺利写了一个Demo,当我运行时候发现,和我期望的不一样!复选框确实创建出来了,但是却没有CSS效果 ...