【问题标题】:Create nested records on parent creation在父创建时创建嵌套记录
【发布时间】:2013-11-22 21:16:58
【问题描述】:

我有一个连接用户模型和报告模型的用户报告模型。 (有很多通过关联)。

我有另一个属于 UserReport 的名为 Comment 的模型。 (有很多联想) 创建报告时,我需要为所有用户创建一个带有一个默认评论的 UserReport。

我的问题是,如果任何一个子记录无法保存,如何以一种回滚报告创建的方式执行此操作。

我的目标是确保数据库不会停留在一致性状态。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    你想要一种叫做交易的东西。代码看起来像

    begin
      Report.transaction do
        # create report like Report.create! or something
        # create comments like Comment.create! or something
      end
    rescue
      # there was an error
    end
    

    在事务内部,如果抛出错误,数据库将恢复到整个事务开始之前的状态。在救援中,您可以处理引发的任何错误。

    【讨论】:

      【解决方案2】:

      当您save 一个模型时,整个过程都包含在一个事务中,如果保存失败(由于验证、回调等),该事务将回滚。因此,如果您首先在内存中构建整个对象树,然后尝试save 报告,那么如果出现任何故障,您的任何对象都不会被保存。

      以下是您可以如何执行此操作的示例:

      # in report.rb
      class Report < ActiveRecord::Base
        validates_associated :user_reports
      end
      
      # in user_report.rb
      class UserReport < ActiveRecord::Base
        validates_associated :comments
      end
      
      # in your controller or wherever you're doing this
      report = Report.new
      User.pluck(:id).each{ |user_id| report.user_reports.build(user_id: user_id) }
      report.user_reports.each{ |user_report| user_report.comments.build }
      report.save # will always save either everything or nothing, no inconsistencies
      

      注意使用#new#build 以避免在最后一行之前提交任何内容。模型中的validates_associated 行会导致子对象上的任何验证错误传播到父对象,即使父对象本身通过验证也无法保存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多