2

我目前在我的 rails 应用程序中有一个计算结构,其中包含模型metric和.operandoperation_type

目前metric模型有很多operands,可以进行基于的计算operation_type(如求和、乘等),每个operand都定义为右或左(即如果运算是除法,就可以识别分子和分母)。

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

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

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

在此处输入图像描述

谁能帮助我以最优雅的方式让操作数成为实际操作数或其他指标?

谢谢!

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

编辑2:好的,我想我到了某个地方 - 基本上我现在有一个指标,它有一个操作数,还有一个操作数有一个指标。我需要一个多态自联接,其中一个指标也可以有许多指标——我是否需要将其称为其他东西,也许是计算的_metrics,以便指标模型可以使用自己?这会让我遇到一个指标有很多操作数,而一个指标有很多计算指标的情况。

编辑 3:我已经更新了我的模型,如下所示,如果对这是否是解决问题的好方法提出任何批评,我将不胜感激。您会注意到,我添加了一个名为的模型,该模型calculated_metric本质上是其他指标的持有者——即可以使用两个操作数或一个操作数和一个计算指标的组合来计算一个指标。

修正模型

编辑 4:为任何可以向我展示详细的 rails-y 方法的人添加了赏金。

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

编辑6:对此没有引起太多关注-增加赏金会有所帮助,还是这个问题不是跑步者?

4

2 回答 2

1

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

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

RDBMS 似乎真的不是这项工作的正确工具。

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

所以用 Ruby 和 Rails 的术语来说。我会做以下事情:

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

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

于 2012-07-11T01:55:44.890 回答
0

如果我正确理解您的问题,我相信您正在寻找Polymorphic Associations

例子:

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
于 2012-07-04T20:04:28.100 回答