2012-01-13 99 views
22

我一直在試圖讓我的腦袋圍繞ActiveRecord協會,但是我碰到了一堵磚牆,不管我多麼複習ActiveRecord文檔,我都無法工作如何解決我的問題。創建或更新has_one ActiveRecord協會

我有兩個類:

Property -> has_one :contract 
Contract -> belongs_to :property 

在我的合同類,我不得不create_or_update_from_xml

首先一個方法我檢查,以確保財產中是否存在問題。

property_unique_id = xml_node.css('property_id').text 
     property = Property.find_by_unique_id(property_unique_id) 
     next unless property 

這是我卡住,我有合同屬性的哈希值,和我想要做的是一樣的東西:

if property.contract.nil? 
    # create a new one and populate it with attributes 
else 
    # use the existing one and update it with attributes 

我知道我會怎麼做呢如果它是原始SQL,但我無法繞過ActiveRecord的方法。

任何提示通過這個路障將非常感激。

在此先感謝。

回答

33
if property.contract.nil? 
    property.create_contract(some_attributes) 
else 
    property.contract.update_attributes(some_attributes) 
end 

應該這樣做。當你有一個has_onebelongs_to關聯,那麼你會得到build_foocreate_foo方法(就像Foo.new和Foo.create)。如果關聯已經存在,那麼property.contract基本上只是一個正常的活動記錄對象。

+0

感謝的是,作品完美。 – 2012-01-16 00:03:23

+0

也許使用空白? – Dan 2017-12-20 08:27:42

7
Property.all.each do |f| 
    c = Contract.find_or_initialize_by(property_id: f.id) 
    c.update(some_attributes) 
end 

我不知道這是否是最好的解決辦法,但對我來說更加簡潔

9

又一個使用Ruby OR-Equal把戲做這件事的方式

property.contract ||= property.build_contract 
property.contract.update_attributes(some_attributes) 
+2

將對象分配給has_one關聯時,會自動保存該對象,這可能會破壞驗證。 http://guides.rubyonrails.org/association_basics.html#has-one-association-reference 使用property.build_contract,除非改爲property.contract。 – 2017-02-04 06:00:33

+0

這是最好的答案,應該被接受。 – ZedTuX 2017-11-04 17:55:03