控制器是受理窗口。
它接请求、拿参数、调业务、决定返回什么。
但它不该变成“一切都写在这里”。
先看一个干净的例子:
class PermitsController < ApplicationController
before_action :set_permit, only: %i[show edit update destroy]
def index
@permits = Permit.order(created_at: :desc)
end
def show
end
def new
@permit = Permit.new
end
def create
@permit = Permit.new(permit_params)
if @permit.save
redirect_to @permit, notice: "施工许可单已创建。"
else
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @permit.update(permit_params)
redirect_to @permit, notice: "施工许可单已更新。"
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@permit.destroy
redirect_to permits_path, notice: "施工许可单已删除。"
end
private
def set_permit
@permit = Permit.find(params[:id])
end
def permit_params
params.expect(permit: [:title, :district, :status, :starts_on])
end
end这里有几件事要看懂:
before_action是窗口前置检查redirect_to是“办完后让你去另一个大厅”render :new, status: :unprocessable_entity是“资料有误,原窗口退回并保留错误信息”permit_params是强参数白名单
关于强参数,要特别提一句:
截至 2026 年的新官方指南里,你会看到 params.expect(...)。
但在大量老项目里,你仍然会经常看到:
params.require(:permit).permit(:title, :district, :status, :starts_on)两种都能遇到。
读老代码别慌,都是工务署在做“只允许这些字段入场”。
控制器最常见的大坑是:
参数校验写这里
SQL 写这里
第三方请求写这里
邮件写这里
权限写这里
报表写这里
事务写这里
返回拼装也写这里然后一个 action 200 行起步。
那不是受理窗口。
那是把整个工务署塞进一个柜台。