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,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
Python
请简述Python中的继承、封装和多态的概念。
【2月更文挑战第24天】【2月更文挑战第82篇】请简述Python中的继承、封装和多态的概念。
|
8月前
|
Go C++
Golang面向对象编程之继承&虚基类【组合&接口】
Golang面向对象编程之继承&虚基类【组合&接口】
|
9月前
|
Python
【Python OOP】类——访问限制
【Python OOP】类——访问限制
|
Java 程序员 数据安全/隐私保护
【Ruby高级技术】对面向对象里的控制访问,包括类的继承类常量的深入理解和使用
【Ruby高级技术】对面向对象里的控制访问,包括类的继承类常量的深入理解和使用
Go-面向对象编程详解(封装、继承、多态等)
Go-面向对象编程详解(封装、继承、多态等)
138 0
Go-面向对象编程详解(封装、继承、多态等)
|
Go PHP
【GO】面向对象:继承性
【GO】面向对象:继承性
89 0
【GO】面向对象:继承性
【GO】面向对象:多态
【GO】面向对象:多态
86 0
【GO】面向对象:多态
|
PHP 数据格式
【laravel】使用trait超类管理公共代码
【laravel】使用trait超类管理公共代码
109 0
【laravel】使用trait超类管理公共代码
|
C# Python 设计模式
python设计模式(五):适配器模式——各种类接口的合并
适配器可以理解为万能接口,各种类可以通过这个接口然后被调用,达到万能转换的效果。 他的实现是以我们定义的适配器函数来分类,将各种类的不同方法注册到对应的分类函数中,调用的时候只需要使用分类名,这样就达到了适配所有类不同方法的效果.
968 0

热门文章

最新文章