【问题标题】:Rails create associated models without saving?Rails 创建关联模型而不保存?
【发布时间】:2016-04-20 14:40:00
【问题描述】:

假设我们有模型 Patient 和 PatientRawData(具有与 Patient 的belongs_to 关联)。

是否可以创建新记录(不保存在数据库中),关联它们,最后保存在数据库中?

类似这样的:

patient = Patient.new(:name => 'John', :age => 34)
rawtext = PatientRawText.new(:rawtext => 'My name is..')
patient.rawtext = rawtext
patient.save!

我想这样做的原因是,在我的真实案例场景中,可能会有更复杂的模型/关联,并且我希望数据库中没有部分内容以防出现异常。

出于这个原因,我更喜欢构建我想要的任何复杂的东西,并作为最后一步将整个东西存储在数据库中。

【问题讨论】:

    标签: ruby-on-rails database in-memory


    【解决方案1】:

    Rails 使用嵌套属性对此类问题提供了开箱即用的支持。 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

    class Patient < ActiveRecord::Base
      has_one :patient_raw_text
      accepts_nested_attributes_for :patient_raw_text
    end
    
    params = { patient: { name: 'Jack', patient_raw_text_attributes: { rawtext: '...' } }}
    member = Patient .create(params[:patient])
    

    【讨论】:

      【解决方案2】:

      您可以使用transaction 来防止创建一堆记录。如果块中的任何地方发生异常,它将回滚所有 ActiveRecord 保存。

      ActiveRecord::Base.transaction do
        patient = Patient.new(:name => 'John', :age => 34)
        rawtext = PatientRawText.create!(:rawtext => 'My name is..')
        patient.rawtext = rawtext
        patient.save! # <- if this fails
        raise "I don't want to be here"  # <- or if you manually raise an exeption 
      end
      

      如果引发异常,即使在成功创建 PatientRawText 对象之后(比如patient.save! 失败),PatientRawText 创建也会回滚。

      【讨论】:

        【解决方案3】:

        是的,Rails 允许我们这样做:

        patient = Patient.new(:name => 'John', :age => 34)
        patient.build_patient_raw_text(:rawtext => 'My name is..')
        patient.save!
        

        【讨论】:

        • 此方法不存在。
        【解决方案4】:

        在实例的引用上使用new 将创建一个未保存的关联模型,其外键将在保存父模型时自动分配。也就是说……

        patient = Patient.new(:name => 'John', :age => 34)
        patient.patient_raw_text.new(:rawtext => 'My name is..')
        patient.save!
        

        和你建议的一样...只是保存一行和局部变量赋值

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-09
          • 1970-01-01
          相关资源
          最近更新 更多