假设以下数据模式:
Usage
======
client_id
resource
type
amount
Billing
======
client_id
usage_resource
usage_type
rate
在这个例子中,假设我有多个资源,每个资源都可以以多种方式使用。例如,一个资源是widget
。 Widgets
可以foo
编辑,可以bar
编辑。 Gizmo
也可以foo
和bar
。这些使用类型以不同的费率计费,对于不同的客户可能甚至是不同的费率。每次(资源的)使用的发生都记录在Usage表中。每个计费率(用于客户,资源和类型组合)都存储在计费表中。
(顺便说一句,如果此数据架构不是解决此问题的正确方法,请提出建议。)
是否可以使用Ruby on Rails和ActiveRecord创建从Billings到Usages的has_many
关系,以便我可以获得给定计费率的使用情况列表?是否有has_many, :through
的语法我不知道?
再一次,我可能会从错误的角度处理这个问题,所以如果你能想出更好的方法,请大声说出来!
答案 0 :(得分:6)
sourceforge显然有一个项目可以扩展Rails的ActiveRecord并支持Composite Primary Keys。我没有使用过此扩展程序,但它可能会对您有所帮助。它也是rubyforge的宝石。
Plain Ruby on Rails,从版本2.0开始,不支持复合主键(参见HowToUseLegacySchemas)。每个表都必须有一个名为“id
”的单列自动增量键。
我所看到的解释是:“如果你想使用遗留数据库,你只需要复合主键。”这当然是一种荒谬无知的数据建模视图。
我看到的解决方案是:
Billing
中明显多余的外键试图强制部分引用完整性。但它并没有完全实现 - 它不会阻止您在Billing
中创建引用Usage
中具有错误的客户端/资源/用法类型组合的行的行,而不是与引用中的行匹配结算表格中的一行。
编辑:@Yarik:是的,你是对的。 Usage
引用Billing
更有意义。
嗯。我制作了一张ER图,但我无法将其作为图像插入。
答案 1 :(得分:1)
您可以在迁移中使用'execute'命令创建所需的任何约束。
您可能希望在.save中添加一些错误处理来处理约束引发错误时的情况。
您不能使用AR的内置方法生成器来生成帐单中的用法,但您仍然可以使用以下方法:
class Billing
def usages
Usage.find(:all, :conditions => ["x = ? and y = ?", self.x, self.y])
end
end