Ruby on rails 关于在Rails应用程序中不使用';我哪儿都不适合

Ruby on rails 关于在Rails应用程序中不使用';我哪儿都不适合,ruby-on-rails,ruby,models,organization,directory,Ruby On Rails,Ruby,Models,Organization,Directory,我想知道是否有关于在Rails应用程序中放置非标准Ruby文件的最佳实践,这些文件不适合任何默认目录(controllers/models等) 我说的是控制器/模型等使用的类,但不是任何Rails基类的子类。类,这些类包含从模型中提取的功能,以减少模型的脂肪。有些看起来像模型,但不是AR模型,有些看起来更像“服务”,有些介于两者之间或其他 几个随机的例子: “策略”类,通过facebook等处理密码身份验证 封装参数的“XParams”对象或处理参数的“XCreator”对象,以执行一些复杂的

我想知道是否有关于在Rails应用程序中放置非标准Ruby文件的最佳实践,这些文件不适合任何默认目录(
controllers
/
models
等)

我说的是控制器/模型等使用的类,但不是任何Rails基类的子类。类,这些类包含从模型中提取的功能,以减少模型的脂肪。有些看起来像模型,但不是AR模型,有些看起来更像“服务”,有些介于两者之间或其他

几个随机的例子:

  • “策略”类,通过facebook等处理密码身份验证
  • 封装参数的“XParams”对象或处理参数的“XCreator”对象,以执行一些复杂的操作,最终导致创建一些AR模型
  • 类,这些类向外部API发出请求或封装这些请求和响应
  • 可替代真实AR模型的假模型(例如来宾用户)
  • 重新安排工作
  • 存储和读取Redis信息的类
  • 类,这些类执行一些特定操作,如处理数据、生成报告等,并从Resque作业或rake任务中调用
我现在有很多这样的程序,其中一些被添加到
lib
中,最后变成了一堆随机的类和模块,一些则潜入
app/models
。我想以某种方式组织一下,但我不知道从哪里开始

是否应仅AR型号进入
应用程序/型号
?或者也可以在那里放置任何域或帮助器模型吗?你如何决定某样东西是否是模型

所有不适合
app
的内容都应该进入
lib
?或者我应该在
应用程序中添加一些新的自定义子目录?哪些子目录,以及如何划分自定义类

在你的项目中你如何处理这个问题?我知道每个项目都有点不同,但肯定有一些相似之处。

我将任何模型类(如STI子类)放在
应用程序/模型中。我将我的其他类放在
lib
中,因为它似乎是放置它们的最佳位置。我很容易知道去哪里找。因为我的模型类都在一个地方,所以对我来说分组测试也更容易


按照惯例,我不愿意将助手类放在
app/models
中。如果它们是演示者类,则属于
应用程序/帮助程序
。如果它们不是,那么
lib
似乎是它们的最佳位置。

通常我的类会进入子目录中的
lib
,其中与子目录同名的模块负责包含它们。(说到自动加载程序,Rails对文件名和类名非常敏感。)


另一种选择是将每个模块封装到自己的gem中,然后通过gem文件引用gem。这允许跨项目共享代码。

您涉及到许多不同的用例,我认为这部分最接近“正确”的答案:

我现在已经有了很多这样的东西,其中一些被添加到lib中,最终成为一堆随机的类和模块,一些潜入到应用程序/模型中。我想以某种方式组织一下,但我不知道从哪里开始

这在我的书中几乎是正确的。你没有提到的一件事是将不同的碎片提取成不同的宝石。与外部服务对话的类是提取的最佳候选类,策略类也是,如果它们足够通用的话。这些可以是私有的,因为运行您自己的gem服务器并不困难,然后您可以在ROR应用程序中重用它们

最后也是最具体的一点是,我将工作重新填充到lib/jobs中


我的经验法则是,如果它是某种型号,它会进入
app/models
。如果不是,它可能属于
lib
或其适当命名的子目录,例如
lib/jobs
lib/extensions
lib/external
,等等。好问题-我没有具体的答案

但我建议你看看这篇文章 - -一定要通读所有的评论

在当前的一个项目中,我在app/models下有大量的非ActiveRecord对象,它可以工作,但并不理想 我将“可重用”的非特定于应用程序的代码放在lib下

我在侧项目上尝试过的其他备选方案(例如,我们有一堆命令对象) rails在应用程序下的名称空间是一个难题,默认情况下,它会将所有内容加载到同一名称空间中

app/
  commands/
    products/create_command.rb         # Products::CreateCommand
    products/update_price_command.rb   # Products::UpdatePriceCommand
或者,除了src或app_name目录下的rails之外的所有内容

app/
  src/
    commands/
      create_product.rb         # Commands::CreateProduct
      update_product_price.rb   # Commands::UpdateProductPrice

我还没有找到一个很好的解决方案,理想情况下,第二个更好,但最好不要在应用下有额外的目录,这样你就可以打开应用并查看控制器、命令、模型等。

如果你感兴趣,稍后我还写了一篇关于这一点的后续文章,总结了我的发现:

+1对于CodeClimate链接,这是到目前为止我在这个主题上看到的最好的资源。上的公认答案也写得很好。我希望有更清楚的答案answers@carbonrCodeClimate这篇文章是我发现的最好的东西,我现在已经把它标记为已接受。“MyTurtleFaceSpace”规则是一个很好的遵循规则。我后来也写了一篇关于这一点的后续文章: