是否可以在轨道中使用复合外键?

时间:2008-11-11 01:47:48

标签: ruby-on-rails database-design has-many

假设以下数据模式:

Usage
======
client_id
resource
type
amount

Billing
======
client_id
usage_resource
usage_type
rate

在这个例子中,假设我有多个资源,每个资源都可以以多种方式使用。例如,一个资源是widgetWidgets可以foo编辑,可以bar编辑。 Gizmo也可以foobar。这些使用类型以不同的费率计费,对于不同的客户可能甚至是不同的费率。每次(资源的)使用的发生都记录在Usage表中。每个计费率(用于客户,资源和类型组合)都存储在计费表中。

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

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

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

2 个答案:

答案 0 :(得分:6)

sourceforge显然有一个项目可以扩展Rails的ActiveRecord并支持Composite Primary Keys。我没有使用过此扩展程序,但它可能会对您有所帮助。它也是rubyforge的宝石。

Plain Ruby on Rails,从版本2.0开始,不支持复合主键(参见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图,但我无法将其作为图像插入。

答案 1 :(得分:1)

您可以在迁移中使用'execute'命令创建所需的任何约束。

您可能希望在.save中添加一些错误处理来处理约束引发错误时的情况。

您不能使用AR的内置方法生成器来生成帐单中的用法,但您仍然可以使用以下方法:

class Billing
  def usages
    Usage.find(:all, :conditions => ["x = ? and y = ?", self.x, self.y])
  end
end