在Rails中,关联是两个Active Record模型之间的关系。关联使用宏的方式实现,用声明的形式为模型添加功能。
Rails支持六种关联:
- belongs_to
- has_one
- has_many
- has_many :through
- has_one :through
- has_and_belongs_to_many
belongs_to关联创建两个模型之间一对一的关系,声明所在的模型实例属于另一个模型的实例。
在belongs_to关联声明中必须使用单数形式。
has_one关联也会建立两个模型之间的一对一关系,表示模型的实例包含或拥有另一个模型的实例。
建立两个模型之间一对多关系。在belongs_to关联的另一端经常使用这个关联。
has_many关联表示模型的实例有零个或是多个另一个模型的实例。
建立两个模型之间多对多关联,这种关联表示一个模型实例可以借由第三个模型,拥有零个或多个另一个模型的实例。
has_many :through还可以用来嵌套的has_many关联。
建立两个模型之间的一对一的关系,这种关联表示一个模型通过第三个模型拥有另一个模型的实例。
这个关联建立两个模型之间多对多关系,不借由第三个模型。
使用belongs_to还是has_one
建立两个模型之间的一对一关系,在一个模型中声明belongs_to,在另一个模型中声明has_one。在哪个模型中声明哪个关联?
不同的声明方式带来的区别是外键放在哪个模型对应的数据表中(外键在声明belongs_to关联所在模型对应的数据库表中)。
使用has_many :through还是has_and_belongs_to_many
Rails提供了两种建立模型之间多对多关系的方法,比较简单的是has_and_belongs_to_many,可直接建立关联。
第二种方法是使用has_many :through,但无法直接建立关联,需要通过第三个模型。
在多态关联中,在同一个关联中,模型可以属于其他多个模型。
class Picture < ActiveRecord::Base belongs_to :imageable, polymorphic: true end class Employee < ActiveRecord::Base has_many :pictures, as: :imageable end class Product < ActiveRecord::Base has_many :pictures, as: :imageable end
在belongs_to中指定使用多态,可以理解为创建一个接口,可供任何一个模型使用。
在Rails中高效的使用Active Record关联,需要了解几个知识点:
- 缓存控制
- 避免命名冲突
- 更新模式
- 控制关联的作用于
- Bi-directional associations
关联添加的方法都会使用缓存,记录最近一次查询结果,以备后用。缓存还会在方法之间共享。
程序其他部分会修改数据,重载缓存,调用方法时传入true即可。
关联的名字不能随意使用。因为创建关联时,会向模型添加同名方法,所以关联的名字不能和Active Record::Base中的实例方法同名。
关联对应的数据库模式需要自己编写。不同的关联类型,要做的事也不同。
对belongs_to来说,要创建外键。
对has_and_belongs_to_many来说,要创建相应的连接数据表
默认情况下,关联只会查找当前模块作用域中的对象。
要想让处在不同命名空间中的模型正常建立关联,声明关联时需要制定完整的类名。
一般情况下,都要求能在关联的两端进行操作。Active Record提供了:inverse_of选项,告知Rails两者之间的关系。
inserse_of限制
- 不能和:through选项同时使用
- 不能和:polymorphic选项同时使用
- 不能和:as选项同时使用
- 在belongs_to关联中,会忽略has_many关联的inverse_of选项
belongs_to关联详解
belongs_to关联创建了一个模型和另一个模型之间一对一的关系,这个类中包含了外键,如果外键在另一个类中,应该使用has_one。
声明belongs_to关联后,所在的类自动获取了五个和关联相关的方法。
has_one关联详解
has_one关联创建了一个模型和另一个模型之间一对一的关系,外键在另一个类中。
has_many关联详解
has_and_belongs_to_many详解