5

假设以下数据模式:

Usage
======
client_id
resource
type
amount

Billing
======
client_id
usage_resource
usage_type
rate

在此示例中,假设我有多个资源,每个资源都可以以多种方式使用。例如,一个资源是widget. Widgets可以foo编辑,他们可以bar编辑。 Gizmos 也可以fooed 和bared。这些使用类型按不同的费率计费,甚至可能针对不同的客户使用不同的费率。每次使用(资源)的出现都记录在使用表中。每个计费费率(针对客户端、资源和类型组合)都存储在计费表中。

(顺便说一句,如果这个数据模式不是解决这个问题的正确方法,请提出建议。)

是否可以使用 Ruby on Rails 和 ActiveRecord 创建has_many从 Billings 到 Usages 的关系,以便我可以获得给定计费率的使用实例列表?有没有has_many, :through我不知道的语法?

再一次,我可能从错误的角度来处理这个问题,所以如果你能想到更好的方法,请说出来!

4

2 回答 2

6

sourceforge 显然有一个项目来扩展 Rails 的 ActiveRecord 并支持Composite Primary Keys。我没有使用过这个扩展,但它可能会对你有所帮助。它也是 ruby​​forge 的瑰宝。

从 2.0 版开始,Plain Ruby on Rails 不支持复合主键(参见HowToUseLegacySchemas)。每个表都必须有一个名为“”的单列自增键id

我看到的解释是:“如果你想使用遗留数据库,你只需要复合主键。” 这当然是对数据建模的一种荒谬无知的看法。

我看到的解决方案是:

  • Usage.client_id -> Client.id
  • Usage.type_id -> Usagetype.id
  • Usage.resource_id -> Resource.id
  • Billing.usage_id -> Usage.id
  • Billing.client_id -> Client.id
  • Billing.type_id -> Usagetype.id
  • Billing.resource_id -> Resource.id

显然是多余的外键,Billing试图强制执行部分引用完整性。但它并没有完全到达那里——它不会阻止您在Billing引用行中创建行,Usage其中包含错误的客户端/资源/使用类型组合,与计费表中引用行中的行不匹配。

编辑: @Yarik:是的,你是对的。Usage参考更有意义Billing

  • Usage.billing_id -> Billing.id

唔。我制作了 ER 图,但无法将其作为图像插入。

于 2008-11-11T02:31:17.920 回答
1

您可以在迁移中使用“执行”命令创建任何您想要的约束。

您可能希望向 .save 添加一些错误处理,以处理约束引发错误的情况。

您不能使用 AR 的内置方法生成器从计费中生成使用情况,但您仍然可以使用以下方法:

class Billing
  def usages
    Usage.find(:all, :conditions => ["x = ? and y = ?", self.x, self.y])
  end
end
于 2009-07-03T23:03:08.830 回答