Polymorphic form--多态表单

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

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

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

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

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

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

 

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

01class 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
19end

 

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

01class 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
37end

 

最后一件事是让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这样就可以访问了。

转载于:https://www.cnblogs.com/wangyuyu/p/3312332.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值