我应该如何在 Rails 中组织复杂的 SQL 视图?

Posted

技术标签:

【中文标题】我应该如何在 Rails 中组织复杂的 SQL 视图?【英文标题】:How should I organize complex SQL views in Rails? 【发布时间】:2010-04-15 16:01:12 【问题描述】:

我使用 Ruby on Rails 管理一个研究数据库。输入的数据主要供科学家使用,他们更喜欢将研究的所有相关信息放在一个巨大的表格中,以便在他们选择的统计软件中使用。我目前将其呈现为 CSV,因为它操作起来非常简单,并且与人们想要使用的工具兼容。

我已经编写了许多视图(SQL 类,而不是 Rails html/ERB 类)来实现他们期望的输出。其中一些视图非常大,并且背后有相当多的复杂性。我用 SQL 编写它们是因为使用 SQL 可以更轻松地完成许多计算和比较。它们当前直接从名为views.sql 的文件加载到数据库中。要获取请求的数据,我会使用select * from my_view;

views.sql 文件变得非常大。部分问题是我们仍在弄清楚我们收集的数据意味着什么,因此一直在对视图进行很多更改——并且正在创建大量视图。其中许多需要可重复。

我最近遇到了组织测试这些视图的问题。 Rails 非常适用于用户界面和业务逻辑,但我不知道有多少现有结构可以处理我们需要的报告。

我想到的一些选项:

我应该以某种方式将它们移动到最相关的模型中吗?几个视图相互交互,这使得这种情况比只做一个find_by_sql 更复杂,所以我不知道它们是否应该只是模型的一部分。 也许它们应该被视为 MVC 意义上的“视图”? (也就是说,它们可以被移动到 app/views/ 并与 HTML 一起存在,可能作为名为 my_view.csv.sql 的文件返回 CSV。)

您将如何处理这样一个复杂的报告问题?

更新为姆拉登·贾布拉诺维奇

开始时有几个视图用于报告目的。我的老板决定他们想要更多,所以我开始写更多。根据我的要求,有些人提供了几百列数据。

我现在有几千行视图都放在一个文件中。我不喜欢这种情况,所以我想重新组织/重构代码。我还想要一种提供 CSV 的简单方法——我目前正在运行查询并手动发送电子邮件,这很容易实现自动化。最后,我希望能够对视图的输出编写一些测试,因为已经弹出了几个回归。

【问题讨论】:

“在 Rails 中组织视图”到底指的是什么?也许你可以举例说明其中的一些? 【参考方案1】:

我没有直接使用 SQL 和视图进行过多的工作,所以我无法帮助您,但您当然可以在视图之上构建 ActiveRecord 模型,事实上非常容易。 《Enterprise Rails》这本书有一整章的内容 (here it is at Google Books)。

【讨论】:

【参考方案2】:

我们在数据库中广泛使用视图,其中一些作为 Rails 模型公开。您可以像使用表格一样使用它们,但当然不能更新它们。

另外,有些列可能会使用其他列(例如不同的比率)计算,所以我们不在视图中执行,而是在模型中执行(好吧,不完全正确,我们构造 SQL sn-p并将其传递给find 调用的:select => '' 部分)。

演示逻辑(例如日期和数字格式)转到 Rails 视图。

恐怕我无法为您提供更具体的建议,因为问题的范围很广。

编辑

数百列听起来不合理。听起来像在一个地方有大量数据。他们如何使用它?我们有 Web 应用程序,他们可以在其中向下钻取和过滤结果、缩小时间跨度和时间步长等,因此报告中的列永远不会超过 10-20 列。

我们为每个 SQL 文件存储一个视图。此外,您可以将其与数字前缀组合以确保正确的创建顺序(以防其中一些依赖于其他)。那里没有迁移,整个 DB 层与应用程序无关。

对于 CSV,您可以创建一组可以手动调用或使用 cron 调用的脚本,也可以使用 Rails 应用程序中的 FasterCSV 并通过 HTTP 请求生成 CSV。

【讨论】:

我添加了对问题的更新。 Mladen,您将视图的代码存储在哪里?你用迁移来制作它们吗?此报告是我的应用程序中不可或缺的一部分,并且变化相当迅速——我不确定我是否喜欢每次报告需要更改时更新迁移的想法。 我对在一个视图中报告这么多列也有同样的感觉。长话短说,这是出于历史原因。我有兴趣改进它,但现实是人们现在仍然需要完成它。 CSV 生成本身不是问题——我已经有它的代码并且知道如何将它集成到我的 Rails 应用程序中。当您说“每个 SQL 文件一个视图”时,您将这些文件保存在哪里?也就是说,您如何/何时创建视图?

以上是关于我应该如何在 Rails 中组织复杂的 SQL 视图?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何在 Rails 中组织这个类似 Instapaper 的功能?

Rails 视图表以显示来自另一个模型的值

SQL 如何查询指定架构中所有表(或视图)的名称

Rails:将复杂的 SQL 查询转换为 Arel 或 ActiveRecord

领域驱动设计 - 层应该如何组织?

Rails 模型/控制器结构