簡體   English   中英

如何在 Rails 中回滾所有最近的事務

[英]How to rollback all recent transactions in Rails

我正在編寫我的第一個 Ruby on Rails 應用程序,但我在管理記錄關聯時遇到了問題。 在這個問題中,具體來說,我想根據下面的代碼向社區征求有關如何將最近的保存回滾到數據庫的建議。

def create
    @aula = Aula.create!(:name => aula_params[:name], :block_duration => aula_params[:block_duration], :rest_time => aula_params[:rest_time], :user_id => @current_user.id)

    if @aula.valid?
      JSON.parse(aula_params[:blocks]).each do |id, b|
        @block = @aula.blocks.create!(:name => b["name"], :sequence_number => id)

        if @block.valid?
          b["workouts"].each do |id, w|
            @block.block_workouts.create!(:workout_id => w["id"], :duration => w["duration"], :sequence_number => id, :repetitions_number => w["repetitions_number"])
          end
        else
          render :json => { message: "Não foi possível criar essa aula", status: 500 }
        end
      end

      render :json => { message: "Aula criada com sucesso", status: 200 }
    else
      render :json => { message: "Não foi possível criar essa aula", status: 500 }
    end
  end

這段代碼基本上創建了一個“aula”,它由多個“塊”組成,而這些塊又由多個“鍛煉”組成。

但是,問題是:假設特定鍛煉的創建失敗。 在這種情況下,應該刪除剛剛創建的“aula”(以及塊及其相關的鍛煉)。 但我找不到以簡潔、優雅的方式做到這一點的方法。

這稱為事務,如果一件事在創建時失敗,所有記錄將回滾

事務是保護塊,其中 SQL 語句只有在它們都可以作為一個原子動作成功的情況下才是永久的。

因此,在您的情況下,您需要將代碼包裝到 Rails 事務中,如下所示:

Aula.transaction do
  @aula = Aula.create!(...)

end

記得使用create! 帶有感嘆號以在失敗時引發錯誤

首先,當您在該塊中創建多個類的對象時,因此我建議在 Aula.transaction 上使用ActiveRecord::Base.transaction Aula.transaction不是特定於該單個 class。

在以下代碼片段中,根據您的關聯僅使用一個aula = @current_user...行。

def create
  ActiveRecord::Base.transaction do
    # Use only any one of below lines
    aula = @current_user.aulas.create!(aula_params) # if user has_many aulas
    aula = @current_user.create_aula!(aula_params) # if user has_one Paula

    JSON.parse(params[:aula][:blocks]).each do |id, b|
      block = aula.blocks.create!(name: b['name'], sequence_number: id)

      block.save!
      b['workouts'].each do |s_id, w|
        block.block_workouts.create!(workout_id: w['id'],
                                     duration: w['duration'],
                                     sequence_number: s_id,
                                     repetitions_number: w['repetitions_number'])
      end
    end

    render json: { message: 'Aula criada com sucesso', status: 200 }
  end
rescue ActiveRecord::RecordInvalid
  render json: { message: 'Não foi possível criar essa aula', status: 500 }
end

def aula_params
  params.require(:aula).permit(:name, :block_duration, :rest_time)
end

我認為這應該可以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM