簡體   English   中英

Rails事務不會在驗證錯誤時回滾

[英]Rails transaction doesn't rollback on validation error

我有兩個模型:用戶和公司。 它們都是從一個表單創建的,我正在使用這樣的事務:

 User.transaction do

  @user.save!

  @company.user = @user
  @company.save!

  @user.reload
  @user.company = @company
  @user.save!

 flash[:notice] = "Thank you for your registration."
  redirect_to_index
end

即使公司的某個驗證失敗,用戶也會保存到數據庫中。 我已經嘗試添加ActiveRecord :: RecordInvalid的顯式錯誤處理,但它沒有幫助。 我認為驗證會引發錯誤以回滾事務。 任何幫助是極大的贊賞。

謝謝

您必須使用支持ACID事務的數據庫引擎。 對於INNODB的mysql。

show table status\G

如果用戶或公司沒有使用InnoDB引擎,您可以使用此命令進行更改。

ALTER TABLE <table name> ENGINE INNODB;

@company.save!拋出的異常@company.save! *應觸發ROLLBACK命令發送到數據庫。 您可以在運行具有DEBUG日志級別的腳本/服務器時在控制台/日志文件中驗證這一點。

嘗試保存新條目並同時修改現有條目(基於新條目),遇到了類似的問題。 使用救援嘗試的交易未通過驗證,但確定了以下內容:

if @new_entry.valid? && @existing_entry.valid?
  ActiveRecord::Base.transaction do
    @new_entry.save!
    @existing_entry.save!
  end
end

代碼首先驗證。 除非兩個條目都有效,否則它不會嘗試保存。 事務語義防止在數據庫支持的情況下對其他錯誤的不完整輸入。 希望這是一個很好的解決方案。

您將不得不考慮這些情況

  1. 使用支持事務的數據庫系統
  2. 重新分解代碼以獲得更合理的方法

例如,如果您只有一對一的關系,則可以以更優化的方式處理它

Company has_one User
User belongs_to Company

現在,在公司模型中

@company.user.build(user_attributes)
@company.save  # will save company as well as user

我沒有測試它作為一個例子。 我的想法。 我是否正確理解了問題?

save()和destroy()總是在事務中(參見http://railsapi.com/doc/rails-v2.3.5/classes/ActiveRecord/Transactions/ClassMethods.html )。

我認為你想做的是

  begin
    @company = Company.create!(params[:company])
    @user    = User.create!(params[:user]) { |user| user.company => @company }
  rescue => ex
    # ... handle your validation errors
  end

這將解決您的問題,因為當公司驗證失敗時,將引發異常並且User.create語句永遠不會執行。

http://tempe.st/2007/05/transaction-in-rails/

我相信你必須在事務循環之外使用一個開始結束塊。

暫無
暫無

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

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