【问题标题】:What's the best way to create a model associated to a query instead of a table创建与查询关联的模型而不是表的最佳方法是什么
【发布时间】:2014-04-29 21:04:26
【问题描述】:

我正在尝试使用 Rails 4 创建一个报告应用程序。 作为一个报告系统,它有很多 SQL 查询,其结果与任何表模式都不同。我的意思是,一个选择查询,其中我有一些连接、联合等,结果将类似于一行,其列是子查询、总和等的结果。

是否有可能有一个没有关联表的模型,但我可以在它上面使用“find_by_sql”,用我的查询结果实例化该模型的数组? 比如:

使用“select table1.field1, sum(if(...,table2.field,...) as field2, as field3 from....”作为查询,返回一个模型数组“Result” ,我可以在这里调用 array_of_result.first.field3?

对不起,如果我写得不够清楚。

编辑: 到目前为止,sparky 的 anwser(http://railscasts.com/episodes/193-tableless-model) 是最接近的,因为我想使用一些 ActiveRecord 功能,例如在类中指定连接(甚至在超级类)。

【问题讨论】:

  • 当然,您可以使用列名作为属性或将列名作为属性的别名

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

对于纯报告,尤其是当结果列名称跨越多个模型时,一种替代方法是直接将查询传回并处理结果集:

ActiveRecord::Base.connection.execute([raw SQL query])

您将返回一个结果集,这通常是一组可枚举的行结果,但请查看您的 DB 适配器的文档以确定它返回的是什么。

例如,如果您使用 PostgreSQL 作为您的数据库和 pg gem,您将返回一个 PG::Result 实例,然后您可以通过以下方式对其进行操作:

 > results = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM customers")
=> <PG:Result >
 > results.count
=> 63   # the number of customers I have in this contrived example
 > results.first
=> { "count": "63" }
 > results[0]
=> { "count": "63" }
 > results[0]["count"]
=> "63"

您需要将返回值转换为字符串以外的内容。 ActiveRecord 通常会在您的模型中为您执行此操作,因为它知道列类型,但是通过执行原始查询,您可能只会返回您必须自己转换的字符串。如果您只是进行查询以将其显示在某处的页面上,那么字符串可能就足够了。

我相信您会做更复杂的报告,但您会注意到在我的简单示例中,键 count 最终被创建为 SELECT COUNT... 查询结果的访问器。如果您指定列名或为其设置别名,则生成的哈希集中的键将与您设置的列名或别名匹配。

【讨论】:

    【解决方案2】:

    您当然可以创建报告模型。

    您可能希望从创建无表模型开始。本质上,这可以像您的模型目录中的文件一样简单

    class Reporting
    end
    

    在其中,以及带有一些适当操作和视图的控制器。不过,看看

    http://railscasts.com/episodes/193-tableless-model

    http://railscasts.com/episodes/219-active-model

    其中涵盖了无表模型以及您可以在验证等方面使用活动模型做什么。

    在你的情况下,你说你有一些复杂的连接等。有时在短期内对这些进行 SQL 化更容易,但如果你可以使用 activerecord,你应该这样做。除此之外,这将允许您在模型中定义自定义方法,您可以链接这些方法并使您的报告控制器更加简洁

    【讨论】:

    • railscasts.com/episodes/193-tableless-model 似乎是一条路,甚至看起来有点“hacky”。您知道将类似 ActiveRecord 的属性与查询中的属性一起使用而不是单个表的最佳方式吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多