将逻辑从控制器转移到模型中是一种很好的做法。但是在任何复杂的系统中,即使大多数方法按照Rails方式是一个衬里,这总会导致一个非常大的文件。
我已经将模型拆分为其他模块并将其包含在原始模型中,例如model_flags
,model_validation
等。任何人都有更好的方法吗?
编辑:我选择了一个建议使用ActiveConcern的新答案。此外,对于任何对组织代码感兴趣的人,本文Making ActiveRecord Models Thin应该会有很大的帮助。
答案 0 :(得分:28)
我意识到这是一个相当古老的问题,并且已被标记为已回答,但它仍然具有良好的Google果汁,因此我认为值得添加...
Rails 3引入了ActiveSupport :: Concern,它可用于模块化模型共享的行为。或者,就此而言,减少变得太胖的模型。
DHH本人在这里提供了一个很好的,简洁的例子:
答案 1 :(得分:6)
出于某些原因,我不会这样做。
首先,你违反了这样的假设:事情将会成为他们应该在哪里,这可能是铁路最大的奖励。如果您在模型中粘贴模型,新人可以轻松地进入您的项目并轻松导航。如果你把它拉出来,你只需添加一个延迟和一些混乱,特别是如果删除某个模块的东西的唯一逻辑是减少模型大小。
第二,你几乎什么也得不到,你就失去了一些东西。如今,当几乎所有编辑器和IDE都能减轻大文件的导航难度时,文件大小并不重要。将内容移动到模块实际上需要一些现代化的便利性,并且需要您和您的同事或未来的维护者在处理一个模型时跳过几个文件。
那就是说我怀疑拥有的铁杆最佳实践会告诉你的是,如果你的模型那么庞大而复杂,那么你的设计是有缺陷的,你的模型可能代表了几个可以分成模型而不是模块的东西。
答案 2 :(得分:4)
好吧,我不会说你把任何东西放在一个模型中都是错的,但我认为将各种问题分开也是非常有效的。这至少是一种折衷。
我正在回答我自己的问题,因为我已经找到了Rails Way来做到这一点: http://github.com/jakehow/concerned_with
可在此处找到更多信息: http://m.onkey.org/2008/9/15/active-record-tips-and-tricks
答案 3 :(得分:2)
不了解你的对象模型,建议有点困难,但我会说,如果你绝对相信所有的验证/关联/回调需要那个地方,仍然有办法分解出共同的行为。因此,虽然我不会只将一大块代码从一个文件移到另一个文件中,而只是重新打开类,我会说使用模块/插件来描述常见的行为类型是一个好主意。 / p>
例如,如果您正在构建一个Facebook-esque活动源,并且所有内容都需要生成“事件”,那么您可能希望将“可事件”行为移动到一个模块中,该模块在包含时定义协会/验证的/ etc。我会说这种方法实际上会增强代码的清晰度,因为在任何地方手动指定这些关联并不像宣布像Eventable那样具有表现力,也不是那么安全(你在一堆地方复制逻辑) ,当逻辑改变时,你知道其余的......)
总而言之,我要说看看你的对象模型。在您的测试套件中,如果您注意到所有测试都需要大量设置,那么这可能是您在对象模型中遗漏某些内容的良好指标。尽管如此,一些示例代码会很棒。
答案 4 :(得分:2)
答案 5 :(得分:0)
模块听起来很明智。我不会将方法调用(验证,回调,插件等)提取到模块中,但是,我将提取限制为我自己的方法。
和往常一样,如果你发布一些示例代码会有所帮助。我发现很难想象清理模型的通用策略,这取决于代码的性质。