Ruby-on-rails 创建或更新 has_one ActiveRecord 关联

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8844185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:36:47  来源:igfitidea点击:

Creating or updating a has_one ActiveRecord association

ruby-on-railsactiverecord

提问by Still Real

I've been trying to get my head around ActiveRecordassociations but I have hit a bit of a brick wall, and no matter how much I review the ActiveRecorddocumentation, I can't work out how to solve my problem.

我一直在尝试解决ActiveRecord关联问题,但我遇到了一些障碍,无论我查看了多少ActiveRecord文档,我都无法弄清楚如何解决我的问题。

I have two classes:

我有两个班级:

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

In my contract class, I have a method to create_or_update_from_xml

在我的合同类中,我有一个方法来 create_or_update_from_xml

First I check to make sure the property in question exists.

首先,我检查以确保有问题的财产存在。

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

And this is where I get stuck, I have a hash of attributes for the contract, and what I want to do is something like:

这就是我陷入困境的地方,我有一个合同属性的哈希值,我想做的是:

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

I know how I would go about it if it was raw SQL, but I can't get my head around hte ActiveRecord approach.

我知道如果它是原始 SQL,我会怎么做,但是我无法理解 ActiveRecord 方法。

Any hints past this road block would be hugely appreciated.

任何通过此路障的提示将不胜感激。

Thanks in advance.

提前致谢。

回答by Frederick Cheung

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

Should do the trick. When you have a has_oneor belongs_toassociation then you get build_fooand create_foomethods (which are like Foo.new and Foo.create). If the association already exists then property.contractis basically just a normal active record object.

应该做的伎俩。当您拥有has_oneorbelongs_to关联时,您将获得build_foocreate_foo方法(类似于 Foo.new 和 Foo.create)。如果关联已经存在,那么property.contract基本上只是一个普通的活动记录对象。

回答by Kinaan Khan Sherwani

Just another way of doing it using ruby OR-Equaltrick

使用 rubyOR-Equal技巧的另一种方法

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

Update:

更新:

@KayWu is right, the above ||= trick will create the contract object in the first line, rather than just building it. An alternative would be

@KayWu 是对的,上面的 ||= 技巧将在第一行创建合约对象,而不仅仅是构建它。另一种选择是

property.build_contract unless property.contract
property.contract.update_attributes(some_attributes)

回答by r-t-t

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

I don't know whether this is the best solution, but for me it more succinctly

我不知道这是否是最好的解决方案,但对我来说更简洁