rails中的多态关联

多态关联--异构对象聚合技术
 
将不同的类(表)聚合(关联)起来
不同的类表现不同,但是具有某些共同的特征
 
下面来举一个例子,对于三个不同的类, Article, Sound, Image,他们的类型不同,表现形式不同,也就是对应表的结构不同:
创建一个rails应用
rails polymorphic
新建三个模型类Article, Sound, Image,对应的数据迁移内容:
#articles
create_table :articles do |t| 
      t.column :content, :text
      t.column :publisher, :string
 
end
#sounds
    create_table :sounds do |t| 
      t.column :content, :binary 
    end
#images
create_table :images do |t| 
      t.column :content, :binary 
      t.column :description, :text
end
而这三者有些共同的特征:
有名称,获得日期等其他的基本信息,通过一个目录表以便查找对应的数据内容。
#catalog_entries
    create_table :catalog_entries do |t| 
      t.column :name, :string 
      t.column :acquired_at, :datetime 
      t.column :resource_id, :integer 
      t.column :resource_type, :string 
    end
在目录这个表中,通过resource_id和resource_type共同组成的外键来决定数据内容。给这个外键起名叫resource
在CatalogEntry中定义:
class CatalogEntry < ActiveRecord::Base 
  belongs_to :resource, :polymorphic => true 
end
在Article类中定义:
class Article < ActiveRecord::Base 
  has_one :catalog_entry, :as => :resource 
end 
在Sound类中定义:
class Sound < ActiveRecord::Base 
  has_one :catalog_entry, :as => :resource 
end 
在Image类中定义:
class Image < ActiveRecord::Base 
  has_one :catalog_entry, :as => :resource 
end 
终端下运行
ruby script/console
 
在最后c.save!执行之后,articles表和catalog_entries表中才有数据写入。
articles表的内容:
 
catalog_entries表内容:
 
 
在终端中做查询:
resource=cat.resource得到的是cat这条目录对应的类的对象!amazing`ha~
 
现在清空数据空,插入代表所有这三种资源的数据:
>> c=CatalogEntry.new(:name=>'Article one', :acquired_at=>Time.now) 
=> #<CatalogEntry id: nil, name: "Article one", acquired_at: "2008-08-31 15:06:4 
9", resource_id: nil, resource_type: nil, created_at: nil, updated_at: nil> 
>> c.resource=Article.new(:content=>"This is my new article", :publisher=>"tyut" 

=> #<Article id: nil, content: "This is my new article", publisher: "tyut", crea 
ted_at: nil, updated_at: nil> 
>> c.save! 
=> true 
>> c=CatalogEntry.new(:name=>'Image One', :acquired_at=>Time.now) 
=> #<CatalogEntry id: nil, name: "Image One", acquired_at: "2008-08-31 15:08:07" 
, resource_id: nil, resource_type: nil, created_at: nil, updated_at: nil> 
>> c.resource=Image.new(:content=>"Some binary data") 
=> #<Image id: nil, content: "Some binary data", description: nil, created_at: n 
il, updated_at: nil> 
>> c.save! 
=> true 
>> c=CatalogEntry.new(:name=>'Sound One', :acquired_at=>Time.now) 
=> #<CatalogEntry id: nil, name: "Sound One", acquired_at: "2008-08-31 15:09:22" 
, resource_id: nil, resource_type: nil, created_at: nil, updated_at: nil> 
>> c.resource=Sound.new(:content=>"more binary data") 
=> #<Sound id: nil, content: "more binary data", created_at: nil, updated_at: ni 
l> 
>> c.save! 
=> true
得到表的内容:
artists:
 
images:
 
 
sounds:
 
catalog_entries:
从第三张表中可以看出,catalog_entry是利用resource_id和resource_type来共同决定资源定位的。
下面遍历catalog_entries表:
>> CatalogEntry.find(:all).each do |c| 
?> puts "#{c.name}: #{c.resource.class}" 
>> end
输出结果:
Article one: Article 
Image One: Image 
Sound One: Sound




本文转自 fsjoy1983 51CTO博客,原文链接:http://blog.51cto.com/fsjoy/96426,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值