[英]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
代碼首先驗證。 除非兩個條目都有效,否則它不會嘗試保存。 事務語義防止在數據庫支持的情況下對其他錯誤的不完整輸入。 希望這是一個很好的解決方案。
您將不得不考慮這些情況
例如,如果您只有一對一的關系,則可以以更優化的方式處理它
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.