当只改变模型时,关系如何神奇地起作用?
如果我想要一个“has__and___belongs___to__many”关系,我应该为包含两个外键的表命名(所以Rails可以使用它)?
答案 0 :(得分:2)
这是有效的,因为您正在遵循“约定优于配置”。
如果您声明客户模型有很多订单,那么rails预计订单表上会有一个customer_id字段。
如果您遵循这些约定,则rails将使用它们,并且能够构建必要的SQL以查找给定客户的所有订单。
如果您在开发应用程序时查看development.log文件,您将能够看到构建必要的SQL以选择给定客户的所有订单。
Rails不会在没有您要求的情况下创建表。通过生成将为您创建/更改表的迁移来实现表的创建。您创建客户模型然后在其中声明has_many:orders的事实不会创建订单表。您需要在迁移过程中为自己创建订单表。在该迁移中,您需要添加customer_id列或使用belongs_to:customer语句将customer_id字段添加到orders表中。
答案 1 :(得分:2)
简短回答:你不能只告诉模特他们有关系;数据库中也必须有列。
当您设置相关模型时,Rails假定您遵循了允许其查找您编写的内容的约定。这是发生的事情:
您设置了表格。
在Rails中遵循约定,您可以以特定的,可预测的方式命名表(复数名词,例如people
)。在此表中,当您与另一个表有关系时,您必须创建该列并以另一种可预测的方式命名(例如bank_account_id
,如果您与bank_accounts
表相关)。< / p>
您编写了一个继承自ActiveRecord :: Base
的模型类 class Person < ActiveRecord::Base
当您实例化其中一个模型时,ActiveRecord :: Base构造函数会查看该类的名称,将其转换为小写并将其复数。在这里,通过阅读Person
,它会产生people
,这是我们之前创建的表的名称。现在,ActiveRecord知道从何处获取有关某人的所有信息,并且它可以读取SQL输出以确定列的内容。
您可以向模型添加关系:has_many
,belongs_to
或has_one
。
当您键入has_many :bank_accounts
之类的内容时,它会假设以下内容:
您所涉及的模型的名称是BankAccount(来自camel-casing :bank_accounts
)。
people
表格中引用银行帐户的列名称为bank_account_id
(来自单一化:bank_accounts
)。
由于关系为has_many
,ActiveRecord知道为您提供类似john.bank_accounts
的方法,使用多个名称。
将所有这些放在一起,ActiveRecord知道如何进行SQL查询,从而为您提供一个人的银行账户。它知道在哪里可以找到所有内容,因为您遵循了在创建表及其列时理解的命名约定。
Ruby的一个优点是你可以在整个类上运行方法,这些方法可以为类添加其他方法。这正是has_many
和朋友正在做的事情。
答案 2 :(得分:0)
此rails guide非常有用