7

登録フォームを持っています。

ユーザーが登録すると、アプリはデータをenrollmentsテーブルとテーブルに保存することになっていusersます。(ユーザーのプロファイルは変更できますが、その特定の登録用に入力したデータをアーカイブする必要があるため、この分離が必要です。したがって、後でユーザーが姓を変更した場合でも、登録フォームに初期情報が表示されます。)

だから私はテーブルにデータを保存することを考えていましenrollmentsた、そしてこのようにafter_create呼び出しをします...

class Enrollment < ActiveRecord::Base

  after_create :save_corresponding_user

  def save_corresponding_user
    user = User.new
    user.full_name = self.user_full_name
    user.email = self.user_email
    user.mobile_phone = self.user_mobile_phone
    user.save
  end
end

問題は、ユーザーの保存が何らかの理由で失敗した場合はどうなるかということです。enrollments保存したばかりのデータをテーブルからロールバックして破棄するにはどうすればよいですか?

4

4 に答える 4

12

falseから戻ってafter_createも何も起こりません。

コールバックチェーン全体がトランザクションにラップされます。beforeコールバックメソッドが正確にfalseを返すか、例外を発生させると、実行チェーンが停止し、ROLLBACKが発行されます。afterコールバックは、例外を発生させることによってのみそれを達成できます。

また、あなたはしなければなりませんraise ActiveRecord::Rollback

ActiveRecord :: Rollback以外の例外は、コールバックチェーンが停止した後、Railsによって再発生します。ActiveRecord :: Rollback以外の例外を発生させると、saveやupdate_attributes(通常はtrueまたはfalseを返そうとします)などのメソッドが例外を発生させることを期待しないコードが破損する可能性があります。

http://guides.rubyonrails.org/active_record_callbacks.html#halting-execution

私はこのようなことをします:

after_create do
  if condition
    errors.add(:attr, 'Blah blah blah.')
    raise ActiveRecord::Rollback
  end
end

Rails 3の場合:http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#halting-execution

于 2015-11-03T20:33:36.670 に答える
11

after_createは、現在のモデルを保存するトランザクションの一部です。したがって、コードがクラッシュした場合、またはafter_createがfalseを返した場合は、現在のトランザクションをロールバックしてenrollment保存を無効にする必要があります。

これをシミュレートする場合は、これをafter_createに追加して、すべてが期待どおりに機能するかどうかを確認してください。

raise Exception.new("CRASH")
于 2012-07-27T17:29:25.607 に答える
1

@anthonyalbertoが述べたように、after_createはすでにトランザクションの一部です。トランザクションを定義するには、コントローラーで次のようなものを使用します。

Enrollment.transaction do
  @enrollment.save!
end

登録の保存が失敗した場合、またはユーザーの保存が失敗した場合は、トランザクション全体がロールバックされます。詳細については、http: //api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.htmlをご覧ください。

于 2012-07-27T18:28:13.737 に答える
1

throw :abortRails 5では、 ActiveRecordチェーンをロールバックするために使用する必要があります。

ここに画像の説明を入力してください

Railsのさまざまなバージョンでの操作処理のリストと、コールバックの前後を確認できます。より明確にするために、実行を停止するという概念を見てください。以下のリンクをたどってください。

https://guides.rubyonrails.org/active_record_callbacks.html#halting-execution

于 2019-07-29T10:37:09.093 に答える