【问题标题】:Creating or updating a has_one ActiveRecord association创建或更新 has_one ActiveRecord 关联
【发布时间】:2012-01-13 00:03:15
【问题描述】:

我一直在努力解决 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,我知道我会怎么做,但我无法理解 ActiveRecord 方法。

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

提前致谢。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:
    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 基本上只是一个正常的活动记录对象。

    【讨论】:

    • 可以用空白吗?
    【解决方案2】:

    使用 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)
    

    【讨论】:

    • 当您将对象分配给 has_one 关联时,该对象会自动保存,这可能会破坏验证。 guides.rubyonrails.org/… 使用 property.build_contract 除非 property.contract 代替。
    • update_attributes 从 Rails 6.1 中被弃用。您可能想更新您的答案以使用 update 代替
    【解决方案3】:
    Property.all.each do |f|
      c = Contract.find_or_initialize_by(property_id: f.id)
      c.update(some_attributes)
    end
    

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

    【讨论】:

      【解决方案4】:

      从 Rails 6.1 开始:

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

      【讨论】:

        猜你喜欢
        • 2017-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        相关资源
        最近更新 更多