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

1.为什么需要关联

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

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

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

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

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

  1. @order = @customer.orders.create(:order_date => Time.now)
  2. @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. class Appointment < ActiveRecord::Base
  6. belongs_to :physician
  7. belongs_to :patient
  8. end
  9. class Patient < ActiveRecord::Base
  10. has_many :appointments
  11. has_many :physicians, :through => :appointments
  12. end

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

  1. class Document < ActiveRecord::Base
  2. has_many :sections
  3. has_many :paragraphs, :through => :sections
  4. end
  5. class Section < ActiveRecord::Base
  6. belongs_to :document
  7. has_many :paragraphs
  8. end
  9. class Paragraph < ActiveRecord::Base
  10. belongs_to :section
  11. 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. class Account < ActiveRecord::Base
  6. belongs_to :supplier
  7. has_one :account_history
  8. end
  9. class AccountHistory < ActiveRecord::Base
  10. belongs_to :account
  11. 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. class Part < ActiveRecord::Base
  5. has_and_belongs_to_many :assemblies
  6. end

2.7.选择belongs_to还是has_one

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

  1. class Supplier < ActiveRecord::Base
  2. has_one :account
  3. end
  4. class Account < ActiveRecord::Base
  5. belongs_to :supplier
  6. 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. class Part < ActiveRecord::Base
  5. has_and_belongs_to_many :assemblies
  6. end
  1. class Assembly < ActiveRecord::Base
  2. has_many :manifests
  3. has_many :parts, :through => :manifests
  4. end
  5. class Manifest < ActiveRecord::Base
  6. belongs_to :assembly
  7. belongs_to :part
  8. end
  9. class Part < ActiveRecord::Base
  10. has_many :manifests
  11. has_many :assemblies, :through => :manifests
  12. 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. class Employee < ActiveRecord::Base
  5. has_many :pictures, :as => :imageable
  6. end
  7. class Product < ActiveRecord::Base
  8. has_many :pictures, :as => :imageable
  9. 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,如需转载请自行联系原作者

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

  1. Rails开发细节《一》

    常用命令 rails new new_app cd new_app rake db:create rails server rails generate controller Blog action1 ...

  2. 【开发细节】用C语言基础写学生管理系统(七)

    前情回顾 完成了所有自定义头文件的编写 一.本次目标 完成程序主入口,一一对应功能实现算法,直到所有功能基本上实现 GitHub:https://github.com/ITchujian/Studen ...

  3. [Ruby on Rails系列]3、初试Rails:使用Rails开发第一个Web程序

    本系列前两部分已经介绍了如何配置Ruby on Rails开发环境,现在终于进入正题啦! Part1.开发前的准备 本次的主要任务是开发第一个Rails程序.需要特别指出的是,本次我选用了一个(Paa ...

  4. LGD模型开发细节|全网首发

    量化风控中始终有个贯穿始终的公式即:ECLPDECL,这三者分别称为: ECL-风险敞口 PD-逾期损失 LGD-违约损失率 上面这三个内容,在番茄风控历史的文章中也稍有提及,特别是ECL与PD写到的 ...

  5. qml开发笔记(七):输入元素鼠标输入MouseArea和键盘输入Keys

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  6. AI 渗透应用程序开发的七种趋势及方法

    2019-11-25 17:12:31 如果你最近一直在关注科技新闻,那么可能已经读到了有关人工智能的新闻,无论好坏.它在你能想到的每个行业都留下了自己的印记.诸如Google,Facebook和Mi ...

  7. 以太坊智能合约开发第七篇:智能合约与网页交互

    原文发表于:以太坊智能合约开发第七篇:智能合约与网页交互 上一篇中,我们通过truffle开发框架快速编译部署了合约.本篇,我们将来介绍网页如何与智能合约进行交互. 编写网页 首先我们需要编写一个网页 ...

  8. 利用vagrant快速搭建rails开发环境

    为什么80%的码农都做不了架构师?>>>    Deprecated 前言 当我们学习一门新的语言或技术的时候,最麻烦或比较浪费时间的事情就是搭建开发环境.而搭建开发环境与我们将要学 ...

  9. docker容器没有apt_使用Docker快速搭建Rails开发环境

    引言 Docker with rails 学习 Ruby On Rails 开发的同学经常会遇到因为电脑系统环境不同,同样的程序在自己这边跑起来没问题,给了其他人之后就是各种依赖或者环境问题,尤其是在 ...

最新文章

  1. 刚刚!刘永坦院士和钱七虎院士荣获2018年度国家最高科技奖
  2. edge新版 能够正则式_Python爬虫七 数据提取之正则
  3. 如何判断字符串所用何种加密编码
  4. 设计模式(二)工厂模式
  5. 【Python学习系列十三】Python机器学习库scikit-learn实现逻辑回归
  6. linux后台运行命令,nohup
  7. oracle 数据泵_如何提升数据泵导出效率?
  8. mysql c 驱动dll_C#调用MySQL数据库(使用MySql.Data.dll连接)mysql-connector-net-6.10.4.msi
  9. Android wpa_supplicant 四次握手 流程分析
  10. ubuntu系统重启后桌面分辨率减小的原因及解决方法
  11. lion.ec开源框架简介(原创)
  12. 使用idea创建项目并通过git上传到码云
  13. 如果赚钱很容易,为什么轮到你?
  14. 计算机一级考试模拟软件安装方法,计算机一级考试软件怎么使用_计算机一级考试软件安装使用教程...
  15. 用IntelliJ IDEA 配置安卓开发环境
  16. 基于HFSS阵列天线设计
  17. Matlab心电信号预处理
  18. 教育行业 服务器虚拟化,教育行业桌面虚拟化方案
  19. 2022年系统架构设计师考试大纲
  20. 理解风险偏好risk appetite vs. 风险容忍度risk tolerance

热门文章

  1. C语言#line预处理器
  2. 历史客人-报表记录信息
  3. 简述python程序执行原理_Python程序的执行原理(1)
  4. 视觉slam学习--坐标系变换 | 欧式变换+仿射变换+射影变换
  5. 人工智能 | 自然语言处理(NLP)(国内外研究组)
  6. php 获取汉字,php 获取汉字长度
  7. #ifdef _DEBUG #define new DEBUG_NEW #endif的解释
  8. js实现kmp算法_「leetcode」459.重复的子字符串:KMP算法还能干这个!
  9. msp430g2553串口接受数据_MSP430G2553串口通信
  10. 国外管理学博士国内计算机博士,教育部认可的国外管理学博士