[Rails] Active Record Association

资料来源:Rails Guide

Guide:

-在模型之间构建关联
-理解不同种类的关联
-使用关联提供的方法

1. Definition:

What? 是模型之间的连接方式
Why? 增强可读性,使得常用的操作变得简单

2. Types:

2.1. Various Types of Associations

belongs_to, has_one, has_many
has_one :through, has_many :through
高级: 单表继承,多态关联,自关联

2.2. Different Choices between Associations

-(1) 选择belongs_to vs has_one: 通过模型数据之间实际的意义来判断
-(2) 选择has_many :through vs has_and_belongs_to_many: 使用前者具有可扩展性

2.3. Advanced Associations:

2.3.1 Polymorphic

多态关联和面向对象的多态不同,它表示一个模型可以通过一个关联属于多个其他模型。可以把多态关联简单的想象成为一个"接口",供任何其他模型使用。注意:需要在数据库层添加外键列和它对应的类型,通过它们可以知道关联的是哪个模型的哪行记录。
t.references :imageable, polymorphic: true, index: true
belongs_to :imageable, polymorphic: true
has_many :pictures, as: :imageable

2.3.2 STI

单表继承和面向对象的继承类似,可共享属性和父类的方法,在同一张表中。可以简单的把它理解为在模型层实现继承,并在数据库层实现操作存储在一张表的机制。注意:需要手动在数据库层添加type字段。除此之外,单表继承还可以给子类定义他所特有的行为,当然在这里可以用到面向对象的多态机制,在父类中定义抽象方法,在子类中具体实现,不知道对象类型的情况下直接调用相同名称的方法得到不同实现。
rails g model sub --parent=super

2.3.3 Self Join

自连接是一个模型通过外键连接自己本身。例如:员工之间的关系,有领导和被领导的关系,但本质上他们都是公司雇佣的劳动力,所以可以使用自关联减少添加其他表。
t.references :manager, index: true
belongs_to :manager, class_name: 'Employee'
has_many: subordinates, class_name: 'Employee', foreign_key: 'manager_id'

3. Tips:

-(1) 控制缓存 关联查询会自动存入缓存中,使用reload可以更新缓存。
-(2) 避免命名冲突 不要使用自带的实例方法名作为关联名称,如attributes
-(3) 更新模式 保证关联的模式与之相匹配,明确数据库层外键是哪一列。
-(4) 控制关联域 当关联的模型属于某个模块时,要是用class_name指定模块名加类名。

4. Gift Methods with Associations:

4.1 belongs_to, has_one

-(1) 赠送的方法:build_association, create_association, create_association!
-(2) 选项:autosave, class_name, dependent, foreign_key, primary_key, validate
---赠送方法之:belongs_tocounter_cache, inverse_of, polymorphic, touch, optional
---赠送方法之:has_oneas, source, source_type, through
-(3) 域: where, includes, readonly, select

4.2 has_many

-(1) 赠送的方法:collection <<, delete, destroy, clear, empty?
size, find, where, exists?, build, create, create!
(collection_singular)_ids, (collection_singular_ids)=(ids)
-(2) 选项:through, class_name, foreign_key, source, dependent
as, autosave, counter_cache, primary_key, inverse_of, source_type, validate
-(3) 域: where, group, includes, limit, offset, order, readonly, select, distinct
Tips: 确保多对多关系中间表的记录在数据库层的唯一性
add_index :readings, [:person_id, :article_id], unique: true

5. Association Callbacks

Triggered by events in the life cycle of a collection.
before_add, after_add, before_remove, after_remove: [:check_sth, :calculate_sth]
private def check_method ... end def calculate_method ... end
如果before_add回调抛出异常,对象不会被添加到关联记录中;
如果before_remove回调抛出异常,对象不会从该关联记录中删除。

6. Association Extension

Add extension methods to associations.
铁轨并没有限制你只能使用它提供的关联方法,你也可以使用自定义的关联方法。这就十分有趣了,你可以通过扩展对象的匿名模块,添加新的查询方法,创建等其他方法。
-(1) 直接在匿名代码块中添加新的关联方发,只属于这个关联
-(2) 使用实名的扩展模块,可在多个关联中共享自定义的关联方法
扩展可以引用内部的关联代理owner, reflection, target

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容