真正的业务系统里,没有对象是孤立的。
- 一个项目有很多许可单
- 一张许可单属于一个项目
- 一张许可单可能有很多检查记录
- 一个检查员可以负责很多检查记录
Rails 用关联把这些关系直接写进模型里。
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把它翻成工务署脑图就是:
Project 1 ---- N Permit 1 ---- N Inspection N ---- 1 Inspector有了关联,很多查询就从“我手写 join”变成“我沿着城市关系图走”。
project = Project.find(1)
project.permits
permit = Permit.find(42)
permit.inspections
inspection = Inspection.last
inspection.inspector但这里也要早点建立一个高级心智:
关联很方便,不代表你可以不关心查询成本。
最典型的大坑就是 N+1:
@permits = Permit.order(created_at: :desc)
@permits.each do |permit|
puts permit.project.name
end如果没预加载,工务署就会来回跑档案馆很多次。
更稳的写法:
@permits = Permit.includes(:project).order(created_at: :desc)所以 Rails 的正确心智不是“有 ORM 就不用懂数据库”。
而是:
先用高层业务语言写,再对查询成本保持工程责任。