2013-10-12 118 views
1

在我的Rails 4應用程序中,我有一個表單將數據提交給兩個不同的模型booking.rbguest.rb。每個模型都必須驗證它們各自的數據,並且只有當腳本的其餘部分繼續時兩者都有效。與find_or_create的軌道交易

我相信交易是前進的方向,事實上我在同一個應用程序中使用了一個交易。

然而,此方案是使用產生@guest實例:

@guest = Guest.find_or_create_by(:email => params[:email]) 

,當然還有,這條線將實際創建記錄,如果它不存在。我的理解是,如果事務真正創建,事務不會回滾?理想情況下,我需要的是這樣的:

@guest = Guest.find_or_new(:email => params[:email]) 

但我不認爲這是在Rails中的選項?

然後我可以繼續下去,並執行事務和回退,如果有一個驗證錯誤:

begin 
    @booking.transaction do 
    @booking.save! 
    @guest.save! 
    end 
    redirect_to somewhere 
rescue 
    render :new 
end 

我的問題我如何可以驗證使用事務兩款車型,同時也考慮到find_or_create_by ?如果事務回滾

+0

你使用哪種數據庫? (SQLite,PostgreSQL,...) –

回答

1

一切都在交易完成時恢復。 (好吧,差不多,有一些特定供應商的陷阱)

只要在交易期間叫做find_or_create也是如此。回滾之後,創建的對象仍在內存中,但後備數據庫行不再存在。

所以只要你的代碼看起來是這樣的,你應該是安全的:

Booking.transaction do 
    @guest = Guest.find_or_create_by(:email => params[:email]) 

    @booking.save! 
    @guest.save! 
end 
+0

我不確定這是必要的,不finde和創建呼叫保存在引擎蓋下? –

+0

我認爲這裏的想法@DrewVerlee是通過保存! (一聲巨響!)它強制保存。使用「!」仍然不適用於我,雖然.....當我在不良事務中調用find_or_create時,即使使用「save!」,我的find_or_create也會回退。 – Shem

+0

不需要guest.save!調用,但它出現在OP的例子中。我只是把它看成是可視化的,如何將原始代碼轉換成單個事務而不重寫整個事物(注意:也可以使用'find_or_create_by!') –