2014-12-02 39 views
1

的得到了与所有has_onebelongs_to关系一个很有趣的情况时,Rails的加载其依赖的模型呈倒的方式。多发HAS_ONE同一类

让我们有一个模型Couple与同一类的两个相关的模型,User

class Couple < ActiveRecord::Base 
    has_one :male, class_name: "User" 
    has_one :female, class_name: "User" 
end 

class User < ActiveRecord::Base 
    belongs_to :couple 
end 

在这种情况下,当我们创建一个Couple并指定其为User两个实例中,我们将进入这个:

# create all the stuff 
couple = Couple.new 
he = User.create name: 'Bob' 
she = User.create name: 'Sara' 
couple.male = he 
couple.female = she 
couple.save 

# here's where the gap begins: 
couple.male.name # => 'Bob' 
couple.female.name # => 'Sara' 

# Ok, so far so good... 
Couple.find(couple.id).male.name # => 'Bob' 

# What's the ..?! 
Couple.find(couple.id).female.name # => 'Bob' 

而我在执行所有这些控制台所看到的,是这样的:

> couple.female.name 
'Sara' 
# nothing happens as the model is loaded already 

> Couple.find(couple.id).female.name 
SELECT `couples`.* FROM `couples` WHERE `couples`.`id` = 2 LIMIT 1 
SELECT `users`.* FROM `users` WHERE `users`.`couple_id` = 2 LIMIT 1 
'Bob' 
# sure, here's the trouble! 

嗯...这不好...在互联网上搜索引导我到这个:我创建了两个类,MaleUserFemaleUser,都来自User模型。并改变了belongs_to :couplebelongs_to :couple, foreign_key: :his_id... :her_id。然而,我在屏幕上看到了同样的结果。

我的问题是,为什么发生这种情况到底如何以正确的方式执行加载?所以Couple.find(couple_id).she会给我适当的对象?

UPD:表结构:

create_table :users do |t| 
    t.integer :couple_id 
    # ... 
end 

create_table :couples do |t| 
    t.integer :his_id 
    t.integer :her_id 
    # ... 
end 

谢谢!

+0

你能还包括两个'User'和'Couple'表迁移/ SQL表结构? – Pete 2014-12-02 00:32:41

+0

@Pete如果这能帮助......然而,没有什么真正有趣的或超自然的存在... – shybovycha 2014-12-02 00:36:04

回答

0

Coupleusers的关系需要是belongs_to的关系,而不是has_one。 E.g:

class Couple < ActiveRecord::Base 
    # ... 
    belongs_to :male, :class_name => 'User', :foreign_key => 'his_id' 
    belongs_to :female, :class_name => 'User', :foreign_key => 'her_id' 
end 

这告诉ActiveRecord的一个Couple有两个User客体关系。一位叫那可以在情侣表的his_id列和一个名为female谁的ID在her_id列中找到发现ID检索male

has_one将在Users表(它不存在)上查找此关系数据。 users表仅引用couple_id,而不引用Couple关系中的用户是男性用户还是女性用户。

+0

但是,这是否任何意义?就像说“夫妻属于男性和女性”一样......这很奇怪......虽然我认为Rails开发人员为了口头上的正确性而添加了这些方法。 – shybovycha 2014-12-02 10:23:44

+0

这些方法在ActiveRecord中以这种方式命名,以指示关系存储在哪个类中。 90%的时间它与英语语言(评论belongs_to博客文章等),但它绝对不会在所有情况下100%完美地阅读。另一种方法是使用单表继承(STI),所以Couple夫妇has_one女性和has_one男性,而不是多个用户。我不知道这是否只是一个假设的例子,但重要的是要记住,一对夫妇也可以是男性或男性或女性/女性。如此有效地夫妇has_many用户也读得更好 – Pete 2014-12-02 11:10:26