我们常听说“上帝对象(God object)”不好,但在某些时候我们都曾创建过或不得不与它交互。最近,作者越来越多地使用 Kasper Timm Hansen 的active_record-associated_object
宝石,它是一个避免创建上帝对象的出色工具。
Kasper 解释得比作者好得多,Rails 应用程序的模型可能会变得很大,Ruby 社区的响应是服务对象,但app/services
有时会变成另一个无用的抽屉。ActiveRecord::AssociatedObject
直接解决了这个问题,它是一个新的领域概念,用于帮助为 Active Record 模型梳理协作对象。
在更新 Flipper Cloud 的定价时,作者意识到如果不加以控制,账户模型会显著膨胀,他们还在创建 Flipper 宝石的付费专业版,这意味着需要设计和构建一种能够处理各种计费结构和支付选项的方法,其中很多新逻辑只与特定账户相关。
对于与单个模型密切相关但不需要持久化自身数据的逻辑,如果不想放在主模型中,有几种选择:上帝对象(将所有逻辑放在主模型中)、更多模型(为每个事物创建额外的数据库模型)、无表模型(创建无表的 PORO 或ActiveModel
类)、关联对象(使用active_record-associated_object
宝石创建“关联对象”)。作者之前大多使用无表模型,后来使用了ActiveRecord::AssociatedObject
,感觉更有意向。
使用ActiveRecord::AssociatedObject
之前,作者的方法是在主模型中添加很多通过self
定义相关对象实例的方法,虽然能完成任务,但感觉不像是 Rails 风格,有很多额外的重复和开销。使用之后,代码更简洁,感觉更像 Rails 风格,减少了样板代码,支持将回调转发到关联对象、扩展主对象、分组相关逻辑、提供定义良好的结构和方法、更好地组织相关代码概念、提供揭示意图的语法、帮助识别和分解特性、与 ActiveJob 和 kredis 集成、有自己的生成器。
通过一些例子展示了ActiveRecord::AssociatedObject
对一些常见事物的 API 的影响,如试验(trial
)、座位(seats
)、定价(pricing
)、权限(entitlements
)等,它为这些逻辑提供了更好的组织方式,在自己的使用中仅触及表面,但已明显改善了领域建模和代码组织,使其更易于推理和测试,是在 Rails 中组织模型逻辑的好方法。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。