如何组织太胖的Rails模型?

将逻辑从控制器转移到模型中是一种很好的做法。 但是在任何复杂的系统中,即使大多数方法按照Rails方式是一个衬里,这也总是导致一个非常大的文件。

我已经将模型拆分成其他模块并将它们包含在原始模型中,例如, model_flagsmodel_validation等。任何人都有更好的方法吗?

编辑:我选择了一个建议使用ActiveConcern的新答案。 此外,对于任何对组织代码感兴趣的人,本文“ 使ActiveRecord模型变薄 ”应该会有很大帮助。

我意识到这是一个相当古老的问题,并且已被标记为已回答,但它仍然具有良好的Google汁液,因此我认为值得添加…

Rails 3引入了ActiveSupport :: Concern,它可用于模块化模型之间共享的行为。 或者,就此而言,减少变得太胖的模型。

DHH本人在这里提供了一个很好的,简洁的例子:

https://gist.github.com/1014971

我不会出于某些原因这样做。

首先,你违背了这样的假设:事情应该是他们应该在哪里,这可能是最初对铁路的最大奖励。 如果您在模型中粘贴模型,新人可以轻松地进入您的项目并轻松导航。 如果你把它拔出来,你只需添加一个延迟和一些混乱,特别是如果删除某个模块的东西的唯一逻辑是减少模型大小。

其次,你几乎从中获得任何东西而你却失去了一些东西 如今几乎所有编辑器和IDE都能减轻大文件的导航难度,文件大小并不重要。 将内容移动到模块实际上需要一些现代的易用性,并且需要您和您的同事或未来的维护者在处理一个模型时跳过几个文件。

这就是说我怀疑拥有的最佳实践团队会告诉你的是,如果你的模型那么庞大而复杂,那么你的设计就会有缺陷,你的模型可能代表了几个可以分成模型而不是模块的东西。

好吧,我不会说你把任何东西放在一个模型中是错的,但我认为能够分开各种各样的问题也是非常有效的。 这至少是一种折衷。

而且我正在发布我自己的问题的答案,因为我已经找到了Rails方法来做到这一点: http : //github.com/jakehow/concerned_with

更多信息可以在这里找到: http : //m.onkey.org/2008/9/15/active-record-tips-and-tricks

不了解你的对象模型,建议有点困难,但我会说,如果你绝对相信所有的validation/关联/回调都需要在那个地方,那么仍有一些因素可以解决共同的行为。 因此,虽然我不会只将一大块代码从一个文件移到另一个文件中,而只是重新打开类,我会说使用模块/插件来描述常见的行为类型是一个好主意。

例如,如果您正在构建一个Facebook-esque活动源,并且所有内容都需要生成“事件”,那么您可能希望将该“可事件”行为移动到一个模块中,该模块在包含时定义了关联/validation/等等。 我会说这种方法实际上会增强代码的清晰度,因为在任何地方手动指定这些关联并不像宣布像Eventable那样具有表现力,也不是那么安全(你在一堆地方复制逻辑) ,当逻辑改变时,你知道其余的……)

总而言之,我会说看看你的对象模型。 在您的测试套件中,如果您注意到所有测试都需要进行大量设置,那么这可能是您在对象模型中遗漏某些内容的良好指标。 尽管如此,一些示例代码会很棒。

  • 您可以使用服务对象: http : //railscasts.com/episodes/398-service-objects
  • 您也可以使用问题。 默认情况下,在rails 4中创建了一个文件夹: http : //railscasts.com/episodes/400-what-s-new-in-rails-4

模块听起来很合理。 我不会将方法调用(validation,回调,插件等)提取到模块中,但是,我将提取限制为我自己的方法。

和往常一样,如果你发布一些示例代码会有所帮助。 我发现很难想象清理模型的通用策略,这取决于代码的性质。