[英]ActiveRecord transaction is not rolling back whole transaction
我有一个票务模型,用户可以从给定的序列号开始购买系列票。 用户选择他们想要购买的门票数量,并且控制器在数据库中生成该门票和商店的数量。 但是,如果一个票证无法保存,则事务应该回滚,但在这种情况下不会。
tickets_controller.rb
...
def create
number = params[:ticket_qty].to_i
@tickets = Array.new
number.times do |n|
t = Ticket.new(ticket_params)
t.serial_number = t.serial_number.to_i + n
@tickets.push(t)
end
respond_to do |format|
ActiveRecord::Base.transaction do
@tickets.each do |t|
if t.save
format.html { redirect_to tickets_path, notice: "#{number} #{"ticket".pluralize(number)} successfully created." }
format.json { render :show, status: :created, location: tickets_path }
else
format.html { render :new, notice: "Some tickets have errors, check the serial number range" }
format.json { render json: @ticket.errors, status: :unprocessable_entity }
end
end
end
end
end
...
此外,重定向是正确的,但没有显示任何通知。
要在发生错误时回滚您的事务,请将t.save
替换为t.save!
这将导致:
respond_to do |format|
begin
ActiveRecord::Base.transaction do
@tickets.each &:save!
format.html { redirect_to tickets_path, notice: "#{number} #{"ticket".pluralize(number)} successfully created." }
format.json { render :show, status: :created, location: tickets_path }
end
rescue ActiveRecord::ActiveRecordError => e
format.html { render :new, notice: "Some tickets have errors, check the serial number range" }
format.json { render json: e.message, status: :unprocessable_entity }
end
end
另一种选择是保存所有记录并根据结果手动触发回滚:
Ticket.transaction do
@save_results = @tickets.map(&:save)
raise ActiveRecord::Rollback unless @save_results.all?
end
respond_to do |format|
if @save_results.all?
format.html # ...
format.json # ...
else
format.html # ...
format.json # ...
end
end
您可以使用@save_results
显示失败记录的数量:
"#{@save_results.count(false)} tickets have errors, ..."
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.