2010-01-11 72 views
8

我有兩個型號導軌 - build_association不工作了HAS_ONE和belongs_to的關係

class Subscription < ActiveRecord::Base 
    belongs_to :client 
end 

class Client < ActiveRecord::Base 
    has_one :subscription 
end 

,但是當我嘗試創建例如從孩子父母sub.build_client外鍵未被設置,例如

>> sub = Subscription.new 
=> #<Subscription id: nil, token: nil, user_id: nil, created_at: nil, updated_at: nil, cancelled: nil, active: nil, client_id: nil> 
>> sub.save(false); 
?> client = sub.build_client 
=> #<Client id: nil, server_id: nil, ip: nil, created_at: nil, updated_at: nil> 
>> client.save(false) 
=> true 
>> sub.client_id 
=> nil 
>> sub 
=> #<Subscription id: 4, token: nil, user_id: nil, created_at: "2010-01-11 06:07:45", updated_at: "2010-01-11 06:07:45", cancelled: nil, active: nil, client_id: nil> 

它的工作,如果我做client.build_subscription

?> client = Client.new 
=> #<Client id: nil, server_id: nil, ip: nil, created_at: nil, updated_at: nil> 
>> client.save(false) 
=> true 
>> sub = client.build_subscription 
=> #<Subscription id: nil, token: nil, user_id: nil, created_at: nil, updated_at: nil, cancelled: nil, active: nil, client_id: 4> 
>> sub.save(false) 
=> true 
>> sub 
=> #<Subscription id: 5, token: nil, user_id: nil, created_at: "2010-01-11 06:09:32", updated_at: "2010-01-11 06:09:32", cancelled: nil, active: nil, client_id: 4> 
>> client 
=> #<Client id: 4, server_id: nil, ip: nil, created_at: "2010-01-11 06:09:02", updated_at: "2010-01-11 06:09:02"> 
>> ^C 

伊夫花了3個小擺弄,得到了無處可去快。 任何人都可以解釋我做錯了什麼,要檢查的東西等

回答

9

根據您的模型協會,SubscriptionClient的孩子。

如果你先創建一個訂閱,然後創建一個客戶,按您的第一個例子,Rails有沒有因爲你還沒有創建客戶端記錄該點設置subscriptions表內的client_id外鍵值的方式,所以沒有什麼可以與訂閱相關聯。這就是爲什麼您必須先創建父記錄(即客戶端),然後使用build_subscription方法將其與子訂閱記錄相關聯。

+0

謝謝約翰,我認爲這是這種情況(我曾經諮詢了導軌指南,但沒有找到這個解釋,所以想在這裏確認在stackoverflow)。但是,如何與has_many屬於關係,這可以做到。 – robodisco 2010-01-11 12:13:41

+0

我只是想,如果它不能做,爲什麼是那裏的構建方法?如果foreign_id不能在這種關係中設置該方法的用途? – robodisco 2010-01-11 12:18:41

+1

這是一個很好的問題。 – 2010-01-11 12:41:53

1

在我的項目中我有很多類似的協會,但我常常禁止CLIENT_ID設置爲空,所以沒有父對象,我不能創建子對象。

嘗試:

sub = Subscription.new 
sub.build_client 
sub.save 

它會創建並保存兩個對象。

0

在其中一個註釋中,您問爲什麼build_client方法在那裏。當您保存在客戶端,然後檢查子的CLIENT_ID,它是零,而且如果你會叫

sub.save(validate: false) 

,然後檢查了子的CLIENT_ID,它會存在。所以儘管它需要額外的保存,但它仍然爲sub創建外鍵的魔力。

1

這似乎已在Rails 4.2.5或更早版本中得到修復。 (我不確定最早的修復版本是什麼,我只測試過4.2.5)

當父母被保存時,插入父記錄後,會自動執行更新以添加父母ID到子記錄。

但是我還沒有找到任何有關此行爲,相關代碼或自動化測試的文檔,所以我不確定它是否有意修復並且應該依賴此行爲。在這裏的其他答案中堅持解決方案可能是最好的。

這也似乎是仍然破壞for_many在Rails 4.2.5。