读书笔记——GROWING RAILS APPLICATIONS IN PRACTICE

问题

Rails 项目随着代码量不断增大,复杂度不断增加,开始越来越难以维护。表现在:

  1. fat controller
    • 不断增加的需求使 controller 塞满了各种 action, 比如 search, order 等等。
    • 某些 action 的逻辑特别复杂,比如 search 会根据 params 实现不同的 filter 逻辑。
  2. fat model
    • 不断增加的需求使 model 塞满了各种 method, scope and callback

fat model 和 controller 降低了代码的可读性和可扩展性,让我们在增加新功能时束手束脚,让测试速度降低,让新人陷入阅读面条代码的痛苦中。

‘Growing Rails Applications In Practice’ (以下简写为 ‘Growing Rails’) 这本书提出了一套解决方法,让 Rails 项目在不断扩张的同时保持良好的可读性和可扩展性。

观点

‘Growing Rails’ 提出了几点观点,书中所有的方法都是建立在这些观点之上的,它们是:

  • complex is complex. 复杂的代码就是复杂的,我们能做的只是用模块的方法管理复杂度
  • we can manage the complexity in Rails way. 我们选择了 Rails 框架,就要利用 Rails 推荐的方法来写代码。也许会有些反直觉的做法,把这当成是一种 trade-off

方法

Better Controller

采用一种一致的 controller 设计:Rails CRUD

咋看上去不适于 CRUD 的交互行为,也 map 到 CRUD 上,比如订阅/退订可以用 subscription create/destroy

Use ActiveRecord’s validation and callback

使用 validation and callback 而不是自定义的方法来保证 model 不被误用

User ActiveRecord-like model

那些不和数据库打交道的交互,比如搜索,登陆等,仍然使用像ActiveRecord一样的建模方式,除了可读性好,心理负担轻以外,还有如下好处:

  • 利用表单,比如 simple_form 的友好的错误提示
  • 自动转换 params 的 string 到 integer 等等格式
  • i18n
  • Transaction

Dealing with fat model

避免 fat model 的关键是多写 model,复杂的就是复杂的,我们只是用模块的方式来管理复杂度。

书中举了一个例子,就像你每天都有一堆邮件寄到家里,你要么做一个邮箱装它们,要么这些邮件就散落在书桌,饭桌,床等各处。”Code never goes away”, 代码不会凭空消失的,我们要么新建一个模块放置它,要么把它散落到现有的模块中。而好的管理方法是一个模块只做一件事。

我们把 model 分成一个核心类和n个附属类,核心类只包括:

  • 最少的 validation, callback 保证数据完整性
  • assciations
  • 通用的 scope

那些只在特定页面出现的特定逻辑不应该放在核心类中:

  • 只在某些页面出现的 validation,比如注册才需要密码
  • 与数据库不一一对应的属性,比如用逗号分隔的tags
  • 只在某些场景需要的 callback, 比如欢迎邮件
  • 权限管理,比如 admin
  • 与 view 有关的 helper

以上这些都应该放在 form model 并在核心类的 namespace 下管理。

结论

提出了一套构建 Rails 项目的方法,不用 SOA, 纯 Rails way。