方案
Customer
和Address
是两个表格。
Customer
包含
class Customer < ActiveRecord::Base
has_one :address, :foreign_key => "id"
end
Address
包含
class Address < ActiveRecord::Base
belongs_to :customer, :foreign_key => "cid"
end
因此,这两个表在id
上匹配,这是默认值,并且该列是自动递增的。
问题 在编辑页面上,我们有一些像这样的代码。
params[:line1] = @customer.first.address.line1
失败,因为在地址表中找不到客户的匹配记录。我不知道为什么会这样。似乎随着时间的推移,很多记录都没有被添加到Address
表中。现在的问题是,当添加新的Customer
时(例如ID为500),Address
将添加一些其他ID(比如425)...现在您不知道哪个地址属于哪个客户。
问题
作为Rails的新手,我想问一下,创建一个额外的列来加入记录总是被认为是好的,而不是依赖于自动递增的列?如果我在Address
表中有一个单独的列,我会手动插入最近添加的客户ID,那么这个问题就不会出现了。
答案 0 :(得分:2)
has_one
- belongs_to
关系应该导致“所属”模型具有“拥有”模型的密钥。或者,换句话说,:foreign_key
子句在两个模型中都应该相同。
如果我有这些:
class Customer < ActiveRecord::Base
has_one :address, :foreign_key => 'cid' # note foreign_key same as in Address
end
class Address < ActiveRecord::Base
belongs_to :customer, :foreign_key => 'cid' # note foreign_key same as in Customer
end
然后我可以这样做:
>> cust = Customer.create(:name=>'Mr Custard')
+----+------------+
| id | name |
+----+------------+
| 1 | Mr Custard |
+----+------------+
1 row in set
>> add = cust.create_address(:line_1 => '42 Some Street', :line_2 => 'Some where')
+----+-----+----------------+------------+
| id | cid | line_1 | line_2 |
+----+-----+----------------+------------+
| 1 | 1 | 42 Some Street | Some where |
+----+-----+----------------+------------+
1 row in set
检查:
>> Customer.first.address
+----+-----+----------------+------------+
| id | cid | line_1 | line_2 |
+----+-----+----------------+------------+
| 1 | 1 | 42 Some Street | Some where |
+----+-----+----------------+------------+
1 row in set
>> Address.first.customer
+----+------------+
| id | name |
+----+------------+
| 1 | Mr Custard |
+----+------------+
我的数据库如下所示:
sqlite> select * from customers;
1|Mr Custard
sqlite> select * from addresses;
1|1|42 Some Street|Some where
(顺便说一句,ActiveRecord结果的漂亮表输出来自Hirb)
答案 1 :(得分:1)
Rails的约定是每个表都有一个名为id
的自动递增整数主键列,另外 - 在您的示例中 - addresses
表具有非自动递增整数名为customer_id
的外键列。顾名思义,它保存了customers
表中相关记录的主键值。
如果您遵循这些规则,则无需在关联中指定:foreign_key
选项。