2011-08-16 27 views
1
class User < ActiveRecord::Base 
    has_many :boxes 
    has_many :books 
end 

class Box < ActiveRecord::Base 
    belong_to :user 
    has_many :books 
end 

class Book < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :box 
end 

所以,当我在一个控制台下方运行它的作品,因为我想到,创建一个新的框和USER_ID连接到箱混淆在ActiveRecord的构建方法

>> u = User.first 
>> u.boxes.build(:height => 3, :width => 1, :length => 4) 
>> u.save 

于是我走得更远,尝试这一点。 box_id已设置,但书中的user_id未设置。

>> u.boxes.first.books.build(:title => 'Reading is fun') 
>> u.save 

看起来好像我在这里错过了一个非常基本的概念。

回答

2

每个关系都与其他所有关系不同。也就是说,当你属于u.boxes.first的一本书build,所有的Rails推断是该书属于该Box;它没有提及用户。

在这种情况下,在(大概)的书总是由谁拥有他们在盒子里的人所拥有的,你可能是最好关闭用has_many :through关系:

class User < ActiveRecord::Base 
    has_many :boxes 
    has_many :books, :through => :boxes 
end 

class Box < ActiveRecord::Base 
    belong_to :user 
    has_many :books 
end 

class Book < ActiveRecord::Base   
    belongs_to: box 
    delegate :user, :to => :box # since belongs_to doesn't take :through 
           # passes Book#user through to Book#box.user 
end 

如果这不是情况下(也许你帮我挪?),离开协会,因为他们,但你必须到了手动设置关系的至少一个,例如:

b = u.boxes.first.books.build(:title => "foo") 
b.user = u 
b.save 

# or... 
u.boxes.first.create_book(:title => "foo", :user => u) 

(其他点的夫妇在你的第二个例子中,你应该保存这本书,而不是用户;并且您可以在create的单个操作中同时执行buildsave

+0

这很有道理。我有一种与has_many:through关系有关的感觉。 – mkly

+0

好的,所以无论如何,我需要将用户标识传递给本书,因为它无法在远处看到。这非常有帮助。谢谢。 – mkly

+0

仅当您不使用':through'时。如果你使用':through','books'表不需要'user_id'列,所有的东西都是通过'Box'模型自动设置的。 – Chowlett

2

这应该是

u.boxes.first.books.build(:title => 'Reading is fun', :user_id => u.id) 

因为你在这里build方法被调用box。和build这样的作品:

parent.children.build 
# The same as: 
parent.children.new(:parent_id => parent.id) 

所以这里没有关于祖父母。

+0

谢谢。这非常有帮助。我希望我可以给你两个检查标记,因为你们都帮助了我。我完全理解。 – mkly

+0

@Mike,\没问题 – fl00r