2011-08-16 23 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