2012-01-13 152 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