Polymorphic form--多态表单

本文详细介绍了在Ruby on Rails项目中通过多态表单创建用户和公司模型的地址表,包括设置model结构、创建Address表、controller操作以及view展示,确保数据库设计的整洁性和灵活性。
摘要由CSDN通过智能技术生成




这是一个在rails中的多态关联的一个简明教程。

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
class Company< ActiveRecord::Base
   has_one :address , :as =>; :addressable , :dependent => :destroy
end
 
class User < ActiveRecord::Base
   has_one :address , :as => :addressable , :dependent => :destroy
end
 
class Address < ActiveRecord::Base
   belongs_to :addressable , :polymorphic => true
end

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CreateAddresses < ActiveRecord::Migration
   def self .up
     create_table :addresses do |t|
       t.string :street_address1 , :null => false
       t.string :street_address2
       t.string :city , :null => false
       t.string :region , :null => false
       t.string :postcode , :null => false , :limit => 55
       t.integer :addressable_id , :null => false
       t.string :addressable_type , :null => false
 
       t.timestamps
     end
   end
 
   def self .down
     drop_table :addresses
   end
end

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class CompaniesController < ApplicationController
 
   def new
     @company = Company. new
     @company .address = Address. new
   end
 
   def edit
     @company = Company.find(params[ :id ])
     @company .address = Address. new unless @company .address != nil
   end
 
   def create
     @company = Company. new (params[ :company ])
     @company .address = Address. new (params[ :address ])
 
     if @company .save
       @company .address.save
       flash[ :notice ] = 'Company was successfully created.'
       redirect_to( @company )
     else
       render :action => 'new'
     end
   end
 
   def update
     @company = Company.find(params[ :id ])
 
     if @company .update_attributes(params[ :company ])
       @company .address.update_attributes(params[ :address ])
       flash[ :notice ] = 'Company was successfully updated.'
       redirect_to( @company )
     else
       render :action => 'edit'
     end
   end
end

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<% form_for( @company ) do |f| %>
     <%= f.error_messages %>
<dl>
         <%= f.text_field :name %>
         <%= f.text_field :telephone %>
         <%= f.text_field :fax %>
         <%= f.text_field :website_url %>
     </dl>
 
     <% fields_for( @company .address) do |address_fields| %>
         <%= address_fields.hidden_field :addressable_id %>
         <%= address_fields.hidden_field :addressable_type %>
<dl>
             <%= address_fields.text_field :street_address1 %>
             <%= address_fields.text_field :street_address2 %>
             <%= address_fields.text_field :city %>
             <%= address_fields.text_field :region %>
             <%= address_fields.text_field :postcode %>
         </dl>
 
     <% end %>
<% end %>

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

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

?
1
2
3
@address = Address.find(params[ :id ])
@address .addressable
这样就可以访问了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值