2010-10-17 48 views
1

在Rails的导的表,我很困惑过为什么has_onehas_many表是相同的:混淆了对HAS_ONE和的has_many

Example tables for has_many

customers(id,name) 
orders(id,customer_id,order_date) 

Example tables for has_one这些在数据库层面,表还将允许供应商拥有多个帐户,但我们只需要每个供应商一个帐户

suppliers(id,name) 
accounts(id,supplier_id,account_number) #Foreign Key to supplier here?? 

不应该为has_one的表是这样的,而不是:

suppliers(id,name,account_id) #Foreign Key to account here 
accounts(id,account_number) 

现在因为account_id是在供应商表,供应商不能有一个以上的账户。

Rails指南中的例子不正确吗?

或者,Rails是否使用has_many类方法,但限制了many部分的发生?

回答

1

如果我正确理解你的问题,你相信有1:1在has_one/belongs_to关系中双向关系。这不完全正确。你可以有:

Class Account 
    belongs_to :supplier 
    belongs_to :wholesaler 
    belongs_to :shipper 
    # ... 
end 

account = supplier.account  # Get supplier's account 
wholesaler = Wholesaler.new 
wholesaler.accounts << account # Tell wholesaler this is one of their suppliers 
wholesaler.save 

我不是说你的应用程序实际上表现为这种方式,但你可以看到一个表 - 不,让我们假设一个模型 - 即“属于”另一种模式,但不排除从属于任何数量的模型。对?所以这种关系真的是无限的:1。

我应该补充一点,has_one实际上是has_many的一个退化情况,只是增加了将关联和其他几个nits单独化的语法糖。否则,它几乎是一回事,这几乎是他们看起来相似的原因。

+0

谢谢!这给了我一些思考的食物。所以,Rails基本上强制has_one中的“one”。我想知道,这是“安全”的。假定只有一个Rails应用程序将使用数据库,它应该没问题。 – Zabba 2010-10-17 06:44:55

+1

Rails的关键指导原则之一是它专为应用程序数据库而非集成数据库而设计。这就是为什么在应用程序级别而不是数据库级别执行约束的原因。它驱动DBA坚果:) – 2010-10-17 17:28:41

2

如果你仔细想想这样的 - 他们都是一样的:

1客户可以有很多订单,所以每个订单的记录点回客户。

1供应商可以有一个帐户,它是“有很多”的特例,所以它同样适用于帐户指向供应商。

多对多的情况也是如此,连接表指向个人记录......(如果学生可以上很多班,而一个班可以有很多学生,那么登记表指向学生和班级记录)。

至于为什么帐户指向供应商vs帐户指向供应商,我不完全确定我们是否可以拥有它,或者一种形式比另一种更好。

+0

我发现了一些链接,可能会有所帮助,只要我仔细研究它们。 http://usernameguy.livejournal.com/5268.html和http://duanesbrain.blogspot.com/2006/05/ruby-on-rails-hasone-versus-belongsto.html。他们对你有意义吗?特别是第二个链接中的信息? – Zabba 2010-10-17 05:07:13

2

我相信它与约束有关。使用has_one导轨将试图强制每个供应商只有一个帐户。但是,对于has_many,将不会执行任何限制,因此具有has_many的供应商将被允许存在多个帐户。

在考虑关系及其在rails中的创建时,需要花费一些时间。如果你想在数据库端执行外键(因为rails不会在应用程序层以外执行此操作),请看看Mathew Higgins' foreigner

+0

明白了。所以Rails使用has_many方法,但强制只有一个记录会被关联 - 正确吗?如果是这样,我想这可能是一件好事,在某种程度上。由于对于某些模型,这可能意味着Rails代码中的一些更改将在未来不会更改数据库的情况下允许has_many。 – Zabba 2010-10-17 06:46:22

+0

本质上,是的。请注意,这样做会使您的数据库瘫痪并且处于较低的完整性水平(在我看来)。很多时候,如果你看看数据库,你可以弄清楚发生了什么。但是,如果所有代码都在应用程序级别上,那么与不同系统和维护的集成可能会很痛苦。并希望你永远不会有某种数据不匹配。 – MunkiPhD 2010-10-18 12:05:51