【发布时间】:2025-12-09 16:20:06
【问题描述】:
将逻辑从控制器转移到模型中是一种很好的做法。但是在任何复杂的系统中,这总是会导致一个非常大的文件,即使大多数方法是按照 Rails 方式的一个衬里。
我已经将模型拆分为其他模块并将它们包含在原始模型中,例如model_flags、model_validation等。谁有更好的方法?
【问题讨论】:
标签: ruby-on-rails model
将逻辑从控制器转移到模型中是一种很好的做法。但是在任何复杂的系统中,这总是会导致一个非常大的文件,即使大多数方法是按照 Rails 方式的一个衬里。
我已经将模型拆分为其他模块并将它们包含在原始模型中,例如model_flags、model_validation等。谁有更好的方法?
【问题讨论】:
标签: ruby-on-rails model
我意识到这是一个相当古老的问题,它已被标记为已回答,但它仍然有很好的 Google 果汁,所以我认为值得添加...
Rails 3 引入了 ActiveSupport::Concern,可用于模块化跨模型共享的行为。或者,就此而言,为那些变得太胖的模特瘦身。
DHH 自己在这里提供了一个简洁的示例要点:
【讨论】:
ActiveSupport::Concern 用于编写具有可重用代码的模型(由许多模型),而模式 concerned_with 是一种将模型拆分为多个部分的简单方法。我喜欢第一个(因为它指示使用 app/ 而不是 lib/),我不确定第二个(看起来很方便,但在概念上很可疑)。
出于几个原因,我不会这样做。
首先,您违反了事物将在它们应该在的地方的假设,这可能首先是 Rails 的最大好处。如果您将模型内容粘贴到模型中,一个新人可以很容易地进入您的项目并导航它。如果你把它拉出来,你只会增加延迟和一些混乱,特别是如果删除模块的唯一逻辑是减小模型大小。
其次,你几乎一无所获,而你又失去了一些东西。如今,几乎所有编辑器和 IDE 都减轻了大文件的导航痛苦,因此文件大小已不再重要。将内容移至模块实际上会消除一些现代的便利性,并且需要您和您的同事或未来的维护人员在处理一个模型时跳过更多的文件。
也就是说,我怀疑核心 Rails 最佳实践团队会告诉您的是,如果您的模型又大又复杂,那么您的设计就有缺陷,并且您的模型可能代表了可以制作成单独模型而不是模块的几个东西.
【讨论】:
好吧,我不会说你们中的任何人将所有内容都放在一个模型中是错误的,但我认为能够分离各种关注点也是非常有效的。这至少是一种权衡。
我正在发布我自己的问题的答案,因为我已经找到了 Rails 方式来做到这一点: http://github.com/jakehow/concerned_with
更多信息可以在这里找到: http://m.onkey.org/2008/9/15/active-record-tips-and-tricks
【讨论】:
不了解您的对象模型,建议您有点困难,但我想说的是,如果您绝对确信所有验证/关联/回调需要那个地方,仍然有一些方法可以分解出常见的行为。因此,虽然我不会将一大段代码从一个文件移到另一个文件中,它只是重新打开类,但我会说使用模块/插件来描述常见类型的行为是一个好主意。
例如,如果您正在构建 Facebook 式的活动提要,并且所有内容都需要生成“事件”,那么您可能希望将“可事件”行为移动到一个模块中,当包含该模块时,它定义了关联/验证/等。我想说这种方法实际上会提高代码的清晰度,因为在任何地方手动指定这些关联并不像将某些东西声明为 Eventable 那样富有表现力,也不安全(你会在很多地方重复逻辑,当逻辑发生变化时,剩下的你就知道了……)
总而言之,我想说仔细看看您的对象模型。在您的测试套件中,如果您注意到所有测试都需要大量设置,那么这可能是一个很好的指标,表明您在对象模型中遗漏了一些东西。不过,再一次,一些示例代码会很棒。
【讨论】:
【讨论】:
模块听起来很明智。我不会将方法调用(验证、回调、插件等)提取到模块中,但我会将提取限制为我自己的方法。
和往常一样,如果您发布一些示例代码会有所帮助。我发现很难想象清理模型的通用策略,这取决于代码的性质。
【讨论】: