如何在Rails中的"around_destroy"中有两个回调?

How to have two callbacks in "around_destroy" in Rails?

尽管这可以按如下方式完成:

class Model < ActiveRecord::Base
  around_destroy :callback

  def callback
    puts 'callback1 before yield'
    puts 'callback2 before yield'
    yield
    puts 'callback1 after yield'
    puts 'callback2 after yield'
  end
end

但我想做以下事情:

class Model < ActiveRecord::Base
  around_destroy :callback1, :callback2

  def callback1
    puts 'callback1 before yield'
    yield
    puts 'callback1 after yield'
  end

  def callback2
    puts 'callback2 before yield'
    yield
    puts 'callback2 after yield'
  end 
end

第二个 'yield' 会发生什么,因为记录可能在第一个 'yield' 中被销毁? (假设一个线程中的所有内容都是 运行 )。 Rails 如何处理这个问题?

或者我应该完全避免第二种方式吗?

它将毫无问题地工作,因为 Active Record 在单个 t运行saction 中包含了这些回调方法。

Since the object is destroyed in first yield, it seems the later is not feasible (assuming everything is running in one thread). How Rails handles this?

不,对象不会在第一次 yield 中被销毁。仅在每个回调方法(after_commit/after_rollback 除外)成功 运行 后才销毁对象。

这里有一个简单的例子来说明这一点。

Class User < ActiveRecord::Base
  around_destroy :callback1, :callback2
  after_commit :after_commit_callback

  def callback1
    puts "Inside First callback, before yield"
    yield
    puts "Inside First callback, after yield"
  end

  def callback2
    puts "Inside Second callback, before yield"
    yield
    puts "Inside Second callback, after yield"
  end

  def after_commit_callback
    puts "after commit callback message"
  end
end

这是必需的控制台命令:

[14] pry(main)> u = User.create(email: "rahul@example.com", password: "testing")
   (0.3ms)  BEGIN
  User Exists (0.4ms)  SELECT  1 AS one FROM `users`  WHERE `users`.`email` = BINARY 'rahul@example.com' LIMIT 1
  SQL (0.4ms)  INSERT INTO `users` (`created_at`, `email`, `encrypted_password`, `updated_at`) VALUES ('2015-06-22 13:01:12', 'rahul@example.com', 'a$h5TYOd20JosN0oVa7ufK.OU3PnHJRi/X6CcTxy7UuDOqYLCIB...u', '2015-06-22 13:01:12')
   (25.8ms)  COMMIT
after commit callback message
=> #<User id: 8, email: "rahul@example.com", encrypted_password: "a$h5TYOd20JosN0oVa7ufK.OU3PnHJRi/X6CcTxy7UuDO...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, name: nil, created_at: "2015-06-22 13:01:12", updated_at: "2015-06-22 13:01:12">
[15] pry(main)> u.destroy
   (0.3ms)  BEGIN
Inside First callback, before yield
Inside Second callback, before yield
  SQL (0.4ms)  DELETE FROM `users` WHERE `users`.`id` = 8
Inside Second callback, after yield
Inside First callback, after yield
   (4.0ms)  COMMIT
after commit callback message
=> #<User id: 8, email: "rahul@example.com", encrypted_password: "a$h5TYOd20JosN0oVa7ufK.OU3PnHJRi/X6CcTxy7UuDO...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, name: nil, created_at: "2015-06-22 13:01:12", updated_at: "2015-06-22 13:01:12">