全书目录

第二十八篇:Ruby on Rails 完全指南 —— 城市脚手架工务署宇宙

第九章:Association —— 城市对象之间不是孤楼,而是整片街区关系

1 分钟 287 字 第 502 / 962 个阅读单元

真正的业务系统里,没有对象是孤立的。

  • 一个项目有很多许可单
  • 一张许可单属于一个项目
  • 一张许可单可能有很多检查记录
  • 一个检查员可以负责很多检查记录

Rails 用关联把这些关系直接写进模型里。

ruby
class Project < ApplicationRecord
  has_many :permits, dependent: :destroy
end

class Permit < ApplicationRecord
  belongs_to :project
  has_many :inspections, dependent: :destroy
end

class Inspection < ApplicationRecord
  belongs_to :permit
  belongs_to :inspector
end

把它翻成工务署脑图就是:

text
Project 1 ---- N Permit 1 ---- N Inspection N ---- 1 Inspector

有了关联,很多查询就从“我手写 join”变成“我沿着城市关系图走”。

ruby
project = Project.find(1)
project.permits

permit = Permit.find(42)
permit.inspections

inspection = Inspection.last
inspection.inspector

但这里也要早点建立一个高级心智:

关联很方便,不代表你可以不关心查询成本。

最典型的大坑就是 N+1:

ruby
@permits = Permit.order(created_at: :desc)

@permits.each do |permit|
  puts permit.project.name
end

如果没预加载,工务署就会来回跑档案馆很多次。

更稳的写法:

ruby
@permits = Permit.includes(:project).order(created_at: :desc)

所以 Rails 的正确心智不是“有 ORM 就不用懂数据库”。

而是:

先用高层业务语言写,再对查询成本保持工程责任。