我一直试图了解ActiveRecord
个关联,但我碰到了一些砖墙,无论我查看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我会怎么做,但我无法理解主动调用方法。
任何通过此路障的提示都将受到极大的赞赏。
提前致谢。
答案 0 :(得分:35)
if property.contract.nil?
property.create_contract(some_attributes)
else
property.contract.update_attributes(some_attributes)
end
应该做的伎俩。当您拥有has_one
或belongs_to
关联时,您将获得build_foo
和create_foo
方法(类似于Foo.new和Foo.create)。如果关联已经存在,则property.contract
基本上只是一个正常的活动记录对象。
答案 1 :(得分:17)
使用ruby OR-Equal
技巧
property.contract ||= property.build_contract
property.contract.update_attributes(some_attributes)
更新:
@KayWu是对的,上面的|| =技巧将在第一行创建合同对象,而不是仅仅构建它。另一种选择是
property.build_contract unless property.contract
property.contract.update_attributes(some_attributes)
答案 2 :(得分:9)
Property.all.each do |f|
c = Contract.find_or_initialize_by(property_id: f.id)
c.update(some_attributes)
end
我不知道这是否是最好的解决方案,但对我来说更简洁