Rails – 可扩展的计算模型

我目前在我的rails应用程序中有一个计算结构,它具有模型metricoperandoperation_type

目前, metric模型具有许多operands ,并且可以基于operation_type (例如,sum,multiply等)执行计算,并且每个operand被定义为向右或向左(即,如果操作是除法,则分子和可以确定分母)。

目前,操作数始终是某个模型的属性,例如@customer.sales.selling_price.sum

为了使这种可伸缩性,需要允许操作数某种属性,或者是先前操作的结果,即操作数可以是度量。

我已经包含了我的模型当前外观的图表:

在此处输入图像描述

任何人都可以帮助我以最优雅的方式允许操作数成为实际操作数或其他指标吗?

谢谢!

编辑:似乎基于迄今为止唯一的答案,也许多态关联是这样做的方式,但答案是如此简短我不知道如何以这种方式使用它们 – 任何人都可以详细说明吗?

编辑2:好的,我想我已经到了某个地方 – 基本上我目前有一个度量标准,其中包含多个操作数,以及一个操作数has_many指标。 我需要一个多态自联接,其中度量也可以有许多度量 – 我是否需要将其称为其他东西,也许是calculate_metrics,以便度量模型可以自己使用? 这将使我的情况是指标具有多个操作数,而指标具有许多calculated_metrics。

编辑3:我已经更新了我的模型如下,并且对于这是否是解决问题的好方法有任何批评。 您将注意到我添加了一个名为calculated_metric的模型,该模型本质上是其他度量的持有者 – 即可以使用两个操作数或操作数和calculated_metric的组合来计算度量。

修订模型

编辑4:Bounty为任何可以向我展示详细的轨道方式的人添加了。

编辑5:赏金仍在争夺中; 虽然下面提供的答案是详细的,但我正在寻找最好的方法,而不是替代方法来处理这个问题(即请让我知道解决问题的最佳方法,而不是寻找方法来回避它,因为我需要这个function)。 谢谢!

编辑6:对此没有太多关注 – 是否会增加赏金帮助,或者这个问题不是跑步者?

考虑退后一步,问自己是否真的需要撕开表达式,并将它们一块一块地存储在关系数据库中。

  • 这对你的目的真的有意义吗?
  • 其他应用程序是否会查询包含表达式片段的基础表?
  • 您是否要生成显示每个运营商使用频率的报告?
  • 或者您是否正在使用关系数据库来存储表达式,因为这是最熟悉的?

RDBMS似乎并不适合这项工作。

您可以将表达式存储为字符串,然后在从文件或数据库加载字符串时将它们解析为表达式树。 有很多示例显示如何编写表达式解析器。

所以把它放在Ruby和Rails术语中。 我会做以下事情:

  1. 将包含表达式树的大多数类放入不扩展ActiveRecord的普通旧Ruby类中。
  2. 在每个类中实现to_s,这样如果您将to_s发送到表达式树的根,您将获得表达式的良好forms的字符串表示forms。
  3. 实现可以从字符串创建表达式树的ExpressionParser或ExpressionBuilder或ExpressionFactory(使用您喜欢的任何术语)。
  4. 然后,如果某些ActiveRecord模型用于指向它独占“拥有”的度量标准,则可以让它指向内存中的表达式树,但是在保存时自己存储字符串表示(通过to_s)。
  5. 如果几个ActiveRecord模型指向旧设计中的相同(共享)表达式,那么您将必须为SharedExpressions创建一个类,该类使用字符串作为持久表示,然后将AciveRecords更改为指向新的SharedExpression。

如果你走这条路线,像before_save这样的ActiveRecord回调可能会有用。 祝好运。

如果我正确理解你的问题,我相信你正在寻找多态关联 。

例:

 class Metric < ActiveRecord::Base belongs_to :calculable, :polymorphic => true has_many :operations, :as => calculable end class Operand < ActiveRecord::Base belongs_to :calculable, :polymorphic => true end