[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

你可能感兴趣的:([Rails] Active Record Association)