如何回滚rails中所有最近的事务

xqnpmsa8  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(249)

我正在编写我的第一个rubyonrails应用程序,但是我在管理记录关联方面遇到了问题。具体来说,在这个问题上,我想根据下面的代码向社区征求关于如何将最近的保存回滚到数据库的建议。

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”(以及相应的块和相关的训练)。但我找不到一个简洁优雅的方法。

hi3rlvi2

hi3rlvi21#

它被称为事务,如果一件事情在创建时失败,所有记录都将回滚https://api.rubyonrails.org/classes/activerecord/transactions/classmethods.html
事务是保护块,其中sql语句只有在它们都可以作为一个原子操作成功时才是永久的。
因此,您需要将代码 Package 到rails事务中,如下所示:

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

end

记住使用 create! 用感叹号表示失败时出错

dzjeubhm

dzjeubhm2#

首先,当您在该块中创建多个类的对象时,我建议使用 ActiveRecord::Base.transaction 结束 Aula.transaction 不是特定于某一类。
在下面的代码段中,只使用一个 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

我想这个应该可以。

相关问题