资讯动态

Rectify Form Object 入门:如何快速把验证逻辑从臃肿 Model 中解放出来

发布时间:2026/8/27 13:39:10 来源:尧图企业网站定制
Rectify Form Object 入门如何快速把验证逻辑从臃肿 Model 中解放出来【免费下载链接】rectifyBuild maintainable Rails apps项目地址: https://gitcode.com/gh_mirrors/re/rectifyRectify 是一款帮助开发者构建可维护 Rails 应用的轻量级 Ruby gem其中的Form Object表单对象组件是解决Model 臃肿问题的第一步它把验证逻辑和入参处理从 Model 中搬出来每个业务场景一个独立的表单类天然替代强参数Strong Parameters白名单。本教程带你用不到 10 分钟完成从安装到落地的完整上手过程。 为什么 Model 会变成大杂烩在典型 Rails 应用中User这类核心 Model 往往承担着过多职责场景化的验证用户自助注册、管理员编辑、用户自我修改三套完全不同的验证规则全部堆进同一个 Modelif/else条件验证越积越多入参处理控制器里一大段params.require(:user).permit(...)业务逻辑发邮件、审计、调用第三方系统全塞在create之后。结果就是那个经典的上帝模型。Rectify 给出的职责划分非常清晰HTTP 请求 Controller 重定向、渲染等 HTTP 相关 数据输入 Form Object 验证、允许哪些输入 业务逻辑 Command 单个用例的业务流程 数据持久化 Model 只做数据关系 数据查询 Query Object 数据库查询 展示逻辑 Presenter 视图格式化Form Object 负责其中数据输入这一层它验证数据、只接收白名单内的属性Model 则可以回归到只做数据关系。核心实现位于 lib/rectify/form.rb基于 Virtus 构建并内置了 ActiveModel 验证能力。 最快安装步骤在Gemfile中加入一行gem rectify然后执行bundle install即可。Rectify 依赖很轻只需要 activemodel / activerecord / activesupport、virtus 和 wisper见 rectify.gemspec你可以只用 Form Object而不必引入它的全部组件。 定义一个 Form Object5 分钟入门官方文档中最经典的示例在 readme.md 的 Form Objects 章节测试代码中也能看到真实用法比如 spec/fixtures/forms/registration_form.rbclass RegistrationForm Rectify::Form attribute :email validates :email, :presence true end就这么简单。继承Rectify::Form用attribute声明允许接收的属性然后像写 Rails 验证一样写validates。对比一下测试夹具里的 spec/fixtures/forms/user_form.rb可以看到嵌套表单、数组属性、mimic等完整能力。 自动替代强参数白名单即声明注意上面的表单里没有出现任何permit。这正是 Form Object 的关键收益你在表单上声明了哪些attribute就只接收哪些属性其余 params 全部被自动忽略。表单声明本身就是白名单控制器不用再维护一份 permit 列表。 自动模拟模型路由和参数键都不用操心Rectify 会用表单类名推断它要模拟mimic的模型——去掉Form后缀即可例如UserForm模拟User。这带来两个便利表单提交走users_path这样的路由辅助方法从 params 中取user这个父键下的数据。如果表单名无法正确推断可以用mimic显式声明class UserForm Rectify::Form mimic :teacher # 提交到 teachers_path读取 params[:teacher] end实现逻辑见 lib/rectify/form.rb 中的infer_model_name方法。 在控制器中使用new / create 完整姿势class UsersController ApplicationController def new form UserForm.new end def create form UserForm.from_params(params) if form.valid? # 做点有意思的事 end end end视图端则可以直接交给 simple_form 等表单构建器% simple_form_for form do |f| % % f.input :first_name % % f.input :last_name % % f.submit % % end %表单对象实现了persisted?、to_key等 ActiveModel 协议因此表单构建器无需任何额外配置即可正常工作。 填充数据的 4 种方式这是 Form Object 最实用的部分四种入口覆盖几乎所有场景方式典型场景UserForm.new(hash)代码中直接传值UserForm.from_params(params)控制器接收请求UserForm.from_model(user)编辑已有记录UserForm.from_json(json)API 请求① from_params除了按父键填充还支持第二个参数传入上下文数据让表单额外接收请求之外的信息form UserForm.from_params(params, :ip_address 1.2.3.4) form.ip_address # 1.2.3.4② from_model自动把模型上同名的属性/方法映射到表单。属性名对不上时实现#map_model方法即可自定义映射。真实示例见 spec/fixtures/forms/user_form.rbdef map_model(model) self.last_login_date model.last_logged_in.strftime(%d/%m/%Y) end③ from_json适合 API 场景按属性名自动匹配。 重要特性表单对象不绑定模型。它只是一个轻量的数据载体——模型只用来填充属性值表单不持有模型的引用也不与模型交互。因此你的表单结构可以完全不同于数据库结构。 深度验证嵌套表单、数组属性与 Deep ContextRectify 的valid?会递归验证嵌套的表单对象和数组中的表单对象这正是注册时同时收集地址和联系人这类场景需要的class UserForm Rectify::Form attribute :name, String attribute :address, AddressForm attribute :contacts, Array[ContactForm] validates :name, :presence true end必要时可以用选项跳过部分验证form.valid?(:exclude_nested true, :exclude_arrays true) 需要当前用户这类上下文用 with_context验证时常需要请求上下文比如检查当前用户是否拥有该资源。把上下文塞给根表单还不够嵌套表单也需要。Rectify 用with_context把上下文透传到所有层级form UserForm.from_params(params).with_context(:user current_user)之后在任意层级的表单里都能通过context访问它validate :check_blog_ownership def check_blog_ownership return if context.user.blogs.exists?(:id blog_id) errors.add(:blog_id, not owned by this user) end这正是每个场景一个 Form Object能彻底消灭 Model 条件验证的原因——场景信息随表单走而不是靠 Model 里的if current_user.admin?。⚙️ 验证前钩子before_validation想在验证前做点预处理比如给空值填默认值重写before_validation即可参考 spec/fixtures/forms/before_validation_form.rbdef before_validation self.email defaulthere.com if email.blank? end 文件放哪里Rectify 建议按功能分组而非按模式分组所有文件放在app下由 Rails 自动加载. └── app ├── controllers ├── core │ ├── billing │ ├── ordering │ └── security ├── models └── views当然建app/forms目录也完全没问题官方文档在 readme.md 的 Where do I put my files? 一节给出了两种方案。⚖️ 适合谁用理性看待取舍Form Object 不是银弹官方文档的 Trade offs 一节说得很实在✅ 应用复杂度超过基础 CRUD、同一模型有多种验证场景时收益明显⚠️ 代价是类和文件变多需要在脑中维护更多小类。官方建议是混合使用复杂业务区域用 Rectify 风格简单 CRUD 保持经典 Rails 写法。对于想继续进阶的读者Form Object 验证完的数据通常交给Command服务对象执行业务流程、由Query Object封装查询、Presenter负责展示逻辑完整用法见 readme.md 各章节Form Object 相关测试可参考 spec/lib/rectify/form_spec.rb。小结Rectify Form Object 用声明式属性白名单 ActiveModel 验证 上下文透传帮你把验证这件事从臃肿 Model 里请了出去。它是让 Rails 应用回归可维护的第一块多米诺骨牌下一步就轮到 Command 了。【免费下载链接】rectifyBuild maintainable Rails apps项目地址: https://gitcode.com/gh_mirrors/re/rectify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价