在rails中的around_destroy中是否可以有两个回调?

时间:2015-06-22 12:05:38

标签: ruby-on-rails activerecord callback

虽然这可以通过以下方式实现:

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

第二次“收益率”会发生什么,因为记录可能在第一次“收益率”中被摧毁? (假设一切都在一个线程中运行)。 Rails如何处理这个?

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

1 个答案:

答案 0 :(得分:1)

它可以毫无问题地工作,因为Active Record会在单个事务中包含这些回调方法。

  

由于对象在第一次产生时被破坏,所以似乎后者不可行(假设一切都在一个线程中运行)。 Rails如何处理这个?

不,对象在第一次收益时不会被销毁。只有在每个回调方法(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', '$2a$10$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: "$2a$10$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: "$2a$10$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">