Rails开发细节《七》ActiveRecord Associations关联

简介:

Rails开发细节《七》ActiveRecord Associations关联

1.为什么需要关联

很多时候,比如说电子商务中的用户和订单,一个用户会有很多的订单,一个订单只属于一个用户,这就是一种关联。

在创建订单的时候需要用户主键作为外键,删除用户的的同时需要删除用户的订单。

在rails中可以向下面这样订单关联。

 
  1. class Customer < ActiveRecord::Base 
  2.   has_many :orders:dependent => :destroy 
  3. end 
  4.   
  5. class Order < ActiveRecord::Base 
  6.   belongs_to :customer 
  7. end 

就可以像下面这样创建订单,删除用户。

 
  1. @order = @customer.orders.create(:order_date => Time.now) 
  2.  
  3. @customer.destroy 

2.关联的类型

有下面6中关联。

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many

 

2.1.belongs_to

belongs_to是一种一对一的关联。表达一种属于的关系。

就像一个订单只能属于个用户。在订单表会有一个字段存储用户主键,这个字段是订单表的外键。

 

 
  1. class Order < ActiveRecord::Base 
  2.   belongs_to :customer 
  3. end 

2.2.has_one

has_one也是一种一对一的关联。表达一种有一个的关系。

就像一个供应商只能有一个账户。账户表有一个供应商主键,是账户表的外键。

 

 
  1. class Supplier < ActiveRecord::Base 
  2.   has_one :account 
  3. end 

2.3.has_many

has_many是一种一对多的关联。表达有多个的关系。

就像一个用户有多个订单。

 

 
  1. class Customer < ActiveRecord::Base 
  2.   has_many :orders 
  3. end 

has_many关联的名称需要使用复数形式。

2.4.has_many :through

has_many是一种多对多的关联。存在一个中间的model。是通过中间model建立关联。

有一个场景就是病人看病,但是需要和医生进行预约。一个医生会有多个预约记录,一个病人也会有多个预约记录。在预约表中会有医生主键和病人主键。

 
  1. class Physician < ActiveRecord::Base 
  2.   has_many :appointments 
  3.   has_many :patients:through => :appointments 
  4. end 
  5.   
  6. class Appointment < ActiveRecord::Base 
  7.   belongs_to :physician 
  8.   belongs_to :patient 
  9. end 
  10.   
  11. class Patient < ActiveRecord::Base 
  12.   has_many :appointments 
  13.   has_many :physicians:through => :appointments 
  14. end 

 

 其实就是把医生和病人的预约关系单独表存放,这张表也会有主键。

 

 
  1. class Document < ActiveRecord::Base 
  2.   has_many :sections 
  3.   has_many :paragraphs:through => :sections 
  4. end 
  5.   
  6. class Section < ActiveRecord::Base 
  7.   belongs_to :document 
  8.   has_many :paragraphs 
  9. end 
  10.   
  11. class Paragraph < ActiveRecord::Base 
  12.   belongs_to :section 
  13. end 

2.5.has_one :through

 

 
  1. class Supplier < ActiveRecord::Base 
  2.   has_one :account 
  3.   has_one :account_history:through => :account 
  4. end 
  5.   
  6. class Account < ActiveRecord::Base 
  7.   belongs_to :supplier 
  8.   has_one :account_history 
  9. end 
  10.   
  11. class AccountHistory < ActiveRecord::Base 
  12.   belongs_to :account 
  13. end 

2.6.has_and_belongs_to_many

has_and_belongs_to_many也是一种多对多的关联。不存在一个中间的model。关系在单独的表中存放,但是这张表没有单独的id,只有双方的id。

 

 
  1. class Assembly < ActiveRecord::Base 
  2.   has_and_belongs_to_many :parts 
  3. end 
  4.   
  5. class Part < ActiveRecord::Base 
  6.   has_and_belongs_to_many :assemblies 
  7. end 

2.7.选择belongs_to还是has_one

belongs_to一般放在有外键的model中,表达一种属于的关系。has_one表达一种拥有的关系。

 

 
  1. class Supplier < ActiveRecord::Base 
  2.   has_one :account 
  3. end 
  4.   
  5. class Account < ActiveRecord::Base 
  6.   belongs_to :supplier 
  7. end 

供应商有一个账号,一个账号属于供应商。

2.8.选择has_many :through还是has_and_belongs_to_many

如果你需要关系model作为独立的实体,就选择has_many :through;不需要独立的实体就选择has_and_belongs_to_many。

 

 
  1. class Assembly < ActiveRecord::Base 
  2.   has_and_belongs_to_many :parts 
  3. end 
  4.   
  5. class Part < ActiveRecord::Base 
  6.   has_and_belongs_to_many :assemblies 
  7. end 

 

 
  1. class Assembly < ActiveRecord::Base 
  2.   has_many :manifests 
  3.   has_many :parts:through => :manifests 
  4. end 
  5.   
  6. class Manifest < ActiveRecord::Base 
  7.   belongs_to :assembly 
  8.   belongs_to :part 
  9. end 
  10.   
  11. class Part < ActiveRecord::Base 
  12.   has_many :manifests 
  13.   has_many :assemblies:through => :manifests 
  14. end 

如果在连接实体上需要验证,回调,或者额外的属性,那就需要使用has_many :through。

2.9.polymorphic

使用polymorphic关联,一个model可以多个model。

就像图片model,既属于员工model,也属于产品model。就是说员工和产品都有图片,他们共享同一个图片model。

 

 
  1. class Picture < ActiveRecord::Base 
  2.   belongs_to :imageable:polymorphic => true 
  3. end 
  4.   
  5. class Employee < ActiveRecord::Base 
  6.   has_many :pictures:as => :imageable 
  7. end 
  8.   
  9. class Product < ActiveRecord::Base 
  10.   has_many :pictures:as => :imageable 
  11. end 

 

 
  1. class CreatePictures < ActiveRecord::Migration 
  2.   def change 
  3.     create_table :pictures do |t| 
  4.       t.string  :name 
  5.       t.integer :imageable_id 
  6.       t.string  :imageable_type 
  7.       t.timestamps 
  8.     end 
  9.   end 
  10. end 

 

 
  1. class CreatePictures < ActiveRecord::Migration 
  2.   def change 
  3.     create_table :pictures do |t| 
  4.       t.string :name 
  5.       t.references :imageable:polymorphic => true 
  6.       t.timestamps 
  7.     end 
  8.   end 
  9. end 

2.10.自连接

有时候,实体会连接自己。

就好比员工表,有些员工同时又是经理,会领导一部分的员工,这样就会造成自连接。

 

 
  1. class Employee < ActiveRecord::Base 
  2.   has_many :subordinates:class_name => "Employee"
  3.     :foreign_key => "manager_id" 
  4.   belongs_to :manager:class_name => "Employee" 
  5. end 

 




本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1019921,如需转载请自行联系原作者

目录
相关文章
|
3月前
|
SQL API 数据库
揭秘Ruby数据库交互的黑科技!ActiveRecord模式:为何它让数据库操作如此“随心所欲”?
【8月更文挑战第31天】在Ruby编程中,与数据库交互至关重要。ActiveRecord作为Ruby on Rails框架的核心组件,凭借其简洁高效的特点,成为处理数据库操作的首选。本文深入探讨ActiveRecord模式,介绍其如何简化数据库交互,并通过示例代码展示具体应用。ActiveRecord是一种ORM框架,将数据库表映射为Ruby类,使开发者能通过操作对象间接管理数据库记录。其核心特性包括模型定义、关联管理、数据验证、事务处理及强大的查询接口。通过示例代码,展示了如何定义模型、创建记录、查询记录及处理关联,突显了ActiveRecord在简化数据库操作方面的优势。
69 0
|
存储 XML SQL
Activiti工作流框架学习笔记(一)之通用数据表详细介绍
Activiti工作流框架学习笔记(一)之通用数据表详细介绍
481 1
|
存储 JSON 数据处理
最为常用的Laravel操作(1)-Eloquent模型
整理了 Laravel 框架 Eloquent 模型最常用的操作,包括一些常用的属性、方法,模型关联等。本系列共有 3 篇文章。
79 2
Laravel Eloquent 关联模型 进阶使用技巧
Laravel Eloquent 关联模型 进阶使用技巧
149 0
新版本 Laravel Eloquent 关联模型 使用技巧
新版本 Laravel Eloquent 关联模型 使用技巧
131 0
|
存储
Git.Framework 框架随手记--存储过程简化
  在很多的ORM中对存储过程操作都是一个棘手的地方,因为存储过程是一段预编译的代码,其中可以包含很多处理过程。在Git.Framework中也同样存在这样的问题,目前没有能力解决这个问题。但是对于存储过程的一些外围操作目前还是可以支持的。
912 0
下一篇
无影云桌面