2017-05-07 6 views
0

ユーザモデルにinvite!というメソッドがあり、ユーザーのために一意のトークンを生成し、自分のアプリケーションに参加/登録するための電子メールを送信します。Railsモデルのデータベーストランザクションのエラーを正しく処理する

簡素化実装がある -

class User < ActiveRecord::Base 
    # ... 
    # ... 

    def invite! 
    transaction do 
     generate_invitation_token 
     mark_as_invited 
     save! 
    end 

    WelcomeMailer.delay.send_invitation(id) 
    end 
end 

あなたが見ることができるように、それはトランザクション内、いくつかのセットアップ手順を行い、その後、WelcomeMailer招待状を送信します。

ここで重要な点は、トランザクション中にデータベースを更新する際に問題がある場合は、電子メールを配信したくないということです。

ここでエラー処理を実装するにはどうすればよいですか?

  1. ルビレベルのメソッドでエラーが発生する可能性があります。たとえば、save!は、一部のモデル検証のためにエラーが発生する可能性があります。その場合はメーラーに届く前にrescuereturnができます。

  2. DBレベルのトランザクションでエラーが発生した場合はどうなりますか?ルビーにバブルアップしてエラーを投げますか?同じbegin..rescueアプローチも同様に働くのでしょうか?

ありがとう!あなたのケースについて

答えて

0

2点: "!!。RecordInvalid - ActiveRecordのが提起::ベース#は保存し、ActiveRecordの::レコードが無効であるBase.create"

  • link
  • "トランザクションブロック内でスローされる例外は(ROLLBACKをトリガした後に)伝播されるため、アプリケーションコード内の例外をキャッチする準備ができているはずです。

    • トランザクションがバック
    • メールをロールバックされます:あなたの現在の単純化されたコード内のトランザクションブロックの内部エラーが発生した場合には次のものがどうなるのか、意味(link

    それはneceだ場合は、エラーがinvite!

から上位throwedされます

  • を送信されませんトランザクションブロック内でエラーが発生した場合にssaryを使用してコードを変更することができます。

    def invite! 
        transaction do 
        generate_invitation_token 
        mark_as_invited 
        save! 
        end 
    rescue RecordInvalid => e 
        # some actions 
        raise e 
    else 
        # code that runs only if *no* exception was raised 
        WelcomeMailer.delay.send_invitation(id) 
    end 
    
  • 関連する問題