【问题标题】:Rails ActiveRecord RelationshipsRails ActiveRecord 关系
【发布时间】:2009-03-28 15:22:46
【问题描述】:

仅更改模型时,关系如何神奇地发挥作用?

如果我想要一个“has__and___belongs___to__many”关系,我应该为包含两个外键的表命名(以便 Rails 可以使用它)?

【问题讨论】:

    标签: ruby-on-rails ruby database activerecord


    【解决方案1】:

    简短回答:您不能只告诉模型它们是相关的;数据库中也必须有列。

    当您设置相关模型时,Rails 假定您已遵循允许它找到您编写的内容的约定。以下是发生的事情:

    1. 你设置了桌子。

      遵循 Rails 中的约定,您可以以特定的、可预测的方式命名表(复数名词,例如 people)。在此表中,当您与另一个表有关系时,您必须创建该列并以另一种可预测的方式命名(例如,bank_account_id,如果您与 bank_accounts 表相关)。

    2. 你编写了一个继承自 ActiveRecord::Base 的模型类

      class Person < ActiveRecord::Base

      当您实例化这些模型之一时,ActiveRecord::Base 构造函数会查看类的名称,将其转换为小写字母并将其复数。在这里,通过读取Person,它产生people,即我们之前创建的表的名称。现在 ActiveRecord 知道从哪里获取有关一个人的所有信息,并且它可以读取 SQL 输出以确定列是什么。

    3. 您向模型添加关系:has_manybelongs_tohas_one

      当您键入 has_many :bank_accounts 之类的内容时,它会假定以下内容:

      1. 与您关联的模型名称是 BankAccount(来自骆驼外壳 @9​​87654332@)。

      2. people 表中引用银行帐户的列的名称是 bank_account_id(来自单数化 :bank_accounts)。

      3. 由于关系是has_many,ActiveRecord 知道给你提供像john.bank_accounts 这样的方法,使用复数名称。

    将所有这些放在一起,ActiveRecord 知道如何进行 SQL 查询,从而为您提供一个人的银行账户。它知道在哪里可以找到所有内容,因为您遵循了在创建表及其列时它理解的命名约定。

    Ruby 的优点之一是您可以在整个类上运行方法,并且这些方法可以将其他方法添加到类中。这正是has_many 和朋友们正在做的事情。

    【讨论】:

    • 那么如果我想要一个“has_and_belongs_to_many”关系,我应该给包含两个外键的表命名(以便 Rails 可以使用它)?
    • 文档是一个很好的资源:@​​987654321@ 解释一下,连接表的约定是每个的复数形式,按词汇顺序。对于 Master 和 Pet 模型,我们将创建表 masters_pets。列应为master_idpet_id
    • 谢谢,这正是我想要的。
    【解决方案2】:

    这有效,因为您遵循“约定优于配置”。

    如果您声明一个客户模型有很多订单,那么 rails 预计订单表中有一个 customer_id 字段。

    如果您遵循了这些约定,那么 rails 将使用它们并能够构建必要的 SQL 来查找给定客户的所有订单。

    如果您在开发应用程序时查看 development.log 文件,您将能够看到正在构建的必要 SQL 以选择给定客户的所有订单。

    Rails 不会在没有您要求的情况下创建表。通过生成将为您创建/更改表的迁移来实现表的创建。您创建一个客户模型,然后在其中声明它 has_many :orders 不会为您创建一个订单表。您需要在迁移中自己执行此操作以创建订单表。在该迁移中,您需要添加 customer_id 列或使用 belongs_to: customer 语句将 customer_id 字段添加到订单表中。

    【讨论】:

    • 我会在答案中提供更多细节。
    【解决方案3】:

    rails guide 非常有用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多