Rails 3.2 - “实用程序”功能在哪里得到保存?

时间:2013-06-17 14:54:29

标签: ruby-on-rails

我想将与对象控制器之外的文件中对象的创建/修改/删除相关的逻辑放在一起。例如,我想从User调用“create_event”方法但我不想做“Event.create()”,因为涉及的各种逻辑都不属于模型。这些文件在哪里?在lib?在Rails 4中这会有什么不同吗?

同样的问题在2009年(Where to put model "utility" functions in Ruby on Rails)被问到,但自从四年前开始,我想确定它仍然是正确的。

3 个答案:

答案 0 :(得分:2)

lib目录通常用于与您的应用无关的逻辑,即您可以在其他项目中重用。您可以将其视为一个目录,您可以将逻辑放在一个宝石上,但它仍然没有。

正如@meagar所说,EventManager是一种很好的方法,因为这段代码将与其他应用程序逻辑一起使用。另一种方法是创建一个EventModule(在app/modules中),在处理事件时将包含辅助方法。

答案 1 :(得分:0)

lib绝对不适合。正如alfonso所说,它适用于可以在不同应用程序中重用的类。就像pdf生成器一样。

Rails中的模型用于持久性和业务逻辑,但是当这种业务逻辑涉及多个时,它变得越来越困难。就个人而言,我喜欢在控制器和模型之间使用服务层来满足这种需求。

我只是在包含类似EventService的类的控制器,模型和视图旁边创建一个文件夹。

EAA : Service layer pattern

Rails 4

Rails 4不会改变

答案 2 :(得分:0)

即使这已经差不多一年了,但我还是想重新审视它,万一其他人偶然发现它。经过大量的考虑后,我最终制作了位于某些模型和控制器之间的服务类,以便处理复杂的表单和关系。这类似于上面链接的EAA : service layer pattern,受到RailsCasts episode 398中建议的Ryan Bates的严重影响。在视频中,Ryan的确切词汇是,"服务对象最适合需要与复杂模型交互的复杂控制器操作,并且没有其他适合该行为的好地方,"这完全描述了我的需求。

在提出我最初的问题时,我是非常环保的,所以它本身并没有真正的措辞。我觉得它想要从模型中取出基本行为,但事实并非如此。我会详细说明,如果其他任何新Rails和/或OOP遇到这种情况并且知道他们想要完成什么但不确切知道如何实现。

就我而言,我使用Neo4j,因此对象之间的关系本身就是对象。在处理复杂的关联时("一个活动有三个乐队和一个场地,表格可以提交新乐队和现有乐队的任意组合,场地加上需要与乐队/场地对象相关联的独特数据或者它们与事件之间的关系......它都是通过事件控制器来实现的;我一直在这些灰色地带发现自己对任务的责任是有问题的。为特定事件设置唯一的频段描述是否是事件的工作? Rails会说它是。它会让我发送我的参数到事件,然后事件将扩展到乐队和地点...但为什么这个事件的工作?为什么Event应该对其他对象做出如此多的反复负责呢?

此外,当某些事情发生时,它有时会成为Waldo用于查找违规代码的地方。是活动模特吗?乐队模特?再次,谁拥有连接点的整个过程?他们是共同的责任。在一天结束时,模型是对象的守门人并控制他们的行为,但模型之间共享信息的守门人是什么?

Ryan Bates在网络广播中实施的服务对象是我的救赎。 Events控制器将表单数据发送到EventManager类。 EventManager将表单拉开,将其中的部分发送到其他专用服务类 - VenueManager和BandManager - 并验证数据,然后使用其关联的模型执行查询和/或在必要时创建新对象。辅助服务类将对象和布尔响应返回给EventManager,然后EventManager根据需要设置关系属性。我的行为是孤立的,更容易测试,阅读和扩展。

由于管理类是具有职责的对象,因此我在每个管理类中都包含ActiveModel::Validations。错误冒出来,如果遇到麻烦,我会感到安全,它会保留一个流程。

任何寻求Ruby OOP建议的人都应该阅读Sandi Metz的Practical Object-Oriented Design in Ruby。阅读和完善那些需要打破自学成才的坏习惯,或者只是想考虑更好地组织代码的方法,这真的是一种快乐。基本的OOP概念让我清楚地知道我的管理对象的责任需要与我的Rails模型分开处理。