【问题标题】:Confusion over the tables for has_one and has_many对 has_one 和 has_many 表的混淆
【发布时间】:2010-10-17 14:02:53
【问题描述】:

在 Rails ActiveRecord Associations 指南中,我对为什么 has_onehas_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 部分发生?

【问题讨论】:

    标签: ruby-on-rails activerecord associations


    【解决方案1】:

    如果你这样想——它们都是一样的:

    1个客户可以有多个订单,因此每个订单记录都指向客户。

    1个供应商可以有一个账户,是“多”的一种特殊情况,所以它同样适用于指向供应商的账户。

    多对多也是同样的情况,连接表指向个人记录……(如果一个学生可以上很多课,一个课可以有很多学生,那么招生表指向返回学生和班级记录)。

    至于为什么帐户指向供应商而不是帐户指向供应商,我不完全确定我们是否可以采用任何一种方式,或者一种形式比另一种更好。

    【讨论】:

    【解决方案2】:

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

    在考虑关系及其在 Rails 中的创建时,确实需要一些时间来适应。如果您想在数据库端强制执行外键(因为 rails 不会在应用层之外执行此操作),请查看 Mathew Higgins' foreigner

    【讨论】:

    • 知道了。所以 Rails 使用 has_many 方法,但强制只关联一条记录——对吗?如果是这样,我想这在某种程度上可能是一件好事。因为对于某些模型,这可能意味着 Rails 代码中的一些更改将允许在未来使用 has_many 而无需更改数据库。?
    • 基本上,是的。请注意,这样做会使您的数据库瘫痪并且完整性水平较低(在我看来)。很多时候,如果您查看数据库,您可以弄清楚发生了什么。但是,如果所有代码都在应用程序级别,那么与不同的系统集成和维护可能会很痛苦。并希望您永远不会出现某种数据不匹配。
    【解决方案3】:

    如果我正确理解您的问题,您认为 has_one/belongs_to 关系中存在双向 1:1 关系。这并不完全正确。你可以:

    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。否则,这几乎是一回事,这就是它们看起来相似的原因。

    【讨论】:

    • 谢谢!这让我深思。因此,Rails 本质上是在 has_one 中强制执行“one”。我想知道,这是否“安全”。假设只有一个 Rails 应用程序会使用数据库,应该没问题。
    • Rails 的主要指导原则之一是它是为应用程序数据库设计的,而不是集成数据库。这就是在应用程序级别而不是数据库级别强制执行约束的原因。它让 DBA 抓狂:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 2012-10-06
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多