active record关联(ruby on rails guides)
来源:互联网 发布:nginx搭建wss环境 编辑:程序博客网 时间:2024/05/29 19:12
Rails 支持六种关联:
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
class Author < ActiveRecord::Base attr_accessible :name has_many :booksendclass Book < ActiveRecord::Base attr_accessible :name, :author_id belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'end
has_many :through
关联
has_many :through
关联经常用于建立两个模型之间的多对多关联。这种关联表示一个模型的实例可以借由第三个模型,拥有零个和多个另一模型的实例。例如,在医疗锻炼中,病人要和医生约定练习时间。这中间的关联声明如下:
class Physician < ApplicationRecord has_many :appointments has_many :patients, through: :appointmentsend class Appointment < ApplicationRecord belongs_to :physician belongs_to :patientend class Patient < ApplicationRecord has_many :appointments has_many :physicians, through: :appointmentsend
has_many :through
还能简化嵌套的 has_many
关联。例如,一个文档分为多个部分,每一部分又有多个段落,如果想使用简单的方式获取文档中的所有段落,可以这么做:
class Document < ApplicationRecord has_many :sections has_many :paragraphs, through: :sectionsend class Section < ApplicationRecord belongs_to :document has_many :paragraphsend class Paragraph < ApplicationRecord belongs_to :sectionend
加上 through: :sections
后,Rails 就能理解这段代码:
@document
.paragraphs
多态关联
关联还有一种高级形式——多态关联(polymorphic association)。在多态关联中,在同一个关联中,一个模型可以属于多个模型。例如,图片模型可以属于雇员模型或者产品模型,模型的定义如下:
class Picture < ApplicationRecord belongs_to :imageable, polymorphic: trueend class Employee < ApplicationRecord has_many :pictures, as: :imageableend class Product < ApplicationRecord has_many :pictures, as: :imageableend
在 belongs_to
中指定使用多态,可以理解成创建了一个接口,可供任何一个模型使用。在 Employee
模型实例上,可以使用@employee.pictures
获取图片集合。
类似地,可使用 @product.pictures
获取产品的图片。
在 Picture
模型的实例上,可以使用 @picture.imageable
获取父对象。不过事先要在声明多态接口的模型中创建外键字段和类型字段:
class CreatePictures < ActiveRecord::Migration[5.0] def change create_table :pictures do |t| t.string :name t.integer :imageable_id t.string :imageable_type t.timestamps end add_index :pictures, [:imageable_type, :imageable_id] endend
控制缓存
关联添加的方法都会使用缓存,记录最近一次查询的结果,以备后用。缓存还会在方法之间共享。例如:
author.books
# 从数据库中检索图书
author.books.size
# 使用缓存的图书副本
author.books.empty?
# 使用缓存的图书副本
应用的其他部分可能会修改数据,那么应该怎么重载缓存呢?在关联上调用 reload
即可:
author.books
# 从数据库中检索图书
author.books.size
# 使用缓存的图书副本
author.books.reload.empty?
# 丢掉缓存的图书副本
# 重新从数据库中检索
Active Record 提供了 :inverse_of
选项,可以通过它明确声明双向关联:
class
Author < ApplicationRecord
has_many
:books
, inverse_of:
'writer'
end
class
Book < ApplicationRecord
belongs_to
:writer
, class_name:
'Author'
, foreign_key:
'author_id'
end
inverse_of
有些限制:
- 不支持
:through
关联; - 不支持
:polymorphic
关联; - 不支持
:as
选项;
class_name
如果另一个模型无法从关联的名称获取,可以使用 :class_name
选项指定模型名。例如,如果一本书属于一位作者,但是表示作者的模型是Patron
,就可以这样声明关联:
class
Book < ApplicationRecord
belongs_to
:author
, class_name:
"Patron"
end
foreign_key
按照约定,用来存储外键的字段名是关联名后加 _id
。:foreign_key
选项可以设置要使用的外键名:
class
Book < ApplicationRecord
belongs_to
:author
, class_name:
"Patron"
,
foreign_key:
"patron_id"
end
primary_key
按照约定,Rails 假定使用表中的 id
列保存主键。使用 :primary_key
选项可以指定使用其他列。
假如有个 users
表使用 guid
列存储主键,todos
想在 guid
列中存储用户的 ID,那么可以使用 primary_key
选项设置:
class
User < ApplicationRecord
self
.primary_key =
'guid'
# 主键是 guid,不是 id
end
class
Todo < ApplicationRecord
belongs_to
:user
, primary_key:
'guid'
end
执行 @user.todos.create
时,@todo
记录的用户 ID 是 @user
的guid
值。
touch
如果把 :touch
选项设为 true
,保存或销毁对象时,关联对象的 updated_at
或updated_on
字段会自动设为当前时间。
class
Book < ApplicationRecord
belongs_to
:author
, touch:
true
end
class
Author < ApplicationRecord
has_many
:books
end
includes
如果经常要直接从商品上获取作者对象(@line_item.book.author
),就可以在关联中把作者从商品引入图书中:
class
LineItem < ApplicationRecord
belongs_to
:book
, -> { includes
:author
}
end
class
Book < ApplicationRecord
belongs_to
:author
has_many
:line_items
end
class
Author < ApplicationRecord
has_many
:books
end
每个 模型实例 都获得了这些方法:
assemblies
assemblies<<(object, ...)
assemblies.delete(object, ...)
assemblies.destroy(object, ...)
assemblies=(objects)
assembly_ids
assembly_ids=(ids)
assemblies.clear
assemblies.empty?
assemblies.size
assemblies.find(...)
assemblies.where(...)
assemblies.exists?(...)
assemblies.build(attributes = {}, ...)
assemblies.create(attributes = {})
assemblies.create!(attributes = {})
- active record关联(ruby on rails guides)
- Ruby On Rails--Active Record Associations(关联关系)
- Ruby on rails --- ActiveRecord基础(SQL和Active Record)
- ruby on rails爬坑(二):Active Record数据库查询
- Ruby On Rails--Active Record Callbacks(回调)
- Ruby On Rails--Active Record Migrations(数据库迁移)
- Ruby On Rails--Active Record Validations(校验)
- Ruby On Rails--Active Record Query Interface(数据库查询)
- Ruby on Rails Guides(一)
- Ruby on rails开发从头来(四十六)- ActiveRecord基础(SQL和Active Record)
- Ruby on rails开发从头来(四十六)- ActiveRecord基础(SQL和Active Record)
- Beginning Ruby on Rails (Wrox Beginning Guides)
- Pro Active Record: Databases with Ruby and Rails
- rails active record associations
- rails active record querying
- Ruby on Rails,一对一关联(One-to-One)
- Ruby on Rails,一对多关联(One-to-Many)
- Ruby on Rails,一对一关联(One-to-One)
- 【python图像处理】python中定义的颜色
- softmax分类算法原理(用python实现)
- 简单理解Socket及TCP/IP、Http、Socket的区别
- [Lintcode] 66. Binary Tree Preorder Traversal
- PHP的错误处理机制
- active record关联(ruby on rails guides)
- [HTML] Meta http-equiv属性详解
- git的一些常用命令
- C++类,构造函数,利用友元判断2个类数据
- 入职第一天,上午完成JBOSS安装配置
- WIN7系统如何与虚拟机Ubuntu系统通过SSH沟通
- python
- poj1611 the suspects(并查集)
- redis统计