在正常的表设计的时候不会发现model引入一对一关系有逻辑问题,但要是遇上不正常的表设计,则要注意处理好model层的一对一关系.
场景:
1个用户拥有一个联系信息
user <--------------- 1:1---------------> contact
一对一的表设计可以把外键关系放在任意一个表.
case 1 将外键关系放在contact表上
|
|
对应model设置一对一关系
|
|
case 2 将外键关系放在user表上
|
|
对应model设置一对一关系
|
|
问题:
观察case1 和 case 2, 可以发现,case1比较正常,表达了user为主表,contact为子表的关系.
然而事实上我们有些情况会将外键关系放在user表上,即case2的情况,而case的model里,却反映的是user表是contact表的一个子表,逻辑上会很奇怪.
问题分析:
这个实际反映出rails中的has_one和belongs_to两个方法的一些trick, 反映出ruby在引用这两个函数时的一些潜归则.
- model A中使用 has_one B时, 要求目标表(B表)必须有A表的外键A_id
- model A中使用belongs_to B时, 要求源表(A表)必须有B表的外键, B_id
这也是对的,数据表设计时本来就没有按正常的逻辑来设计表的外键关系(r),就必须遵遁ROR的函数规则.
stackoverflow也讲到这一点了:http://stackoverflow.com/questions/861144/ruby-on-rails-has-one-question
class Person < ActiveRecord::Base
has_one :cell # the cell table has a person_id
end
class Cell < ActiveRecord::Base
has_one :person # the person table has a cell_id
end
class Person < ActiveRecord::Base
belongs_to :cell # the person table has a cell_id
end
class Cell < ActiveRecord::Base
belongs_to :person # the cell table has a person_id
end
所以要特别注意一下.