[英]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.