Spec-Zone.ru › Ruby on Rails 8.1

module ActiveSupport::Callbacks

Обратные вызовы Active Support

Обратные вызовы — это хуки кода, которые выполняются в ключевые моменты жизненного цикла объекта. Обычно базовый класс определяет набор обратных вызовов, относящихся к предоставляемым им функциям, чтобы подклассы могли устанавливать обратные вызовы, расширяющие или изменяющие базовую функциональность, без необходимости переопределять или заново определять методы базового класса.

Подключение этого модуля позволяет определять события в жизненном цикле объекта, для которых будут поддерживаться обратные вызовы (с помощью ClassMethods#define_callbacks), задавать вызываемые методы экземпляра, процедуры или объекты обратного вызова (с помощью ClassMethods#set_callback) и запускать установленные обратные вызовы в нужное время (с помощью run_callbacks).

По умолчанию обратные вызовы прерываются с помощью throw :abort. Подробнее см. ClassMethods#define_callbacks.

Поддерживаются три вида обратных вызовов: обратные вызовы before, выполняемые перед определённым событием; обратные вызовы after, выполняемые после события; и обратные вызовы around — блоки, окружающие событие и запускающие его при вызове yield. Код обратного вызова может содержаться в методах экземпляра, процедурах или лямбдах, а также в объектах обратного вызова, отвечающих на определённые заранее заданные методы. Подробнее см. ClassMethods#set_callback.

class Record
  include ActiveSupport::Callbacks
  define_callbacks :save

  def save
    run_callbacks :save do
      puts "- save"
    end
  end
end

class PersonRecord < Record
  set_callback :save, :before, :saving_message
  def saving_message
    puts "saving..."
  end

  set_callback :save, :after do |object|
    puts "saved"
  end
end

person = PersonRecord.new
person.save

Вывод:

saving...
- save
saved

Константы

CALLBACK_FILTER_TYPES

Общедоступные методы экземпляра

run_callbacks (kind, type = nil) { || ... } Показать исходный код
# File activesupport/lib/active_support/callbacks.rb, line 97
def run_callbacks(kind, type = nil)
  callbacks = __callbacks[kind.to_sym]

  if callbacks.empty?
    yield if block_given?
  else
    env = Filters::Environment.new(self, false, nil)

    next_sequence = callbacks.compile(type)

    # Common case: no 'around' callbacks defined
    if next_sequence.final?
      next_sequence.invoke_before(env)
      env.value = !env.halted && (!block_given? || yield)
      next_sequence.invoke_after(env)
      env.value
    else
      invoke_sequence = Proc.new do
        skipped = nil

        while true
          current = next_sequence
          current.invoke_before(env)
          if current.final?
            env.value = !env.halted && (!block_given? || yield)
          elsif current.skip?(env)
            (skipped ||= []) << current
            next_sequence = next_sequence.nested
            next
          else
            next_sequence = next_sequence.nested
            begin
              target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
              target.send(method, *arguments, &block)
            ensure
              next_sequence = current
            end
          end
          current.invoke_after(env)
          skipped.pop.invoke_after(env) while skipped&.first
          break env.value
        end
      end

      invoke_sequence.call
    end
  end
end

Запускает обратные вызовы для указанного события.

Вызывает обратные вызовы before и around в порядке их задания, выполняет блок (если он передан), а затем запускает обратные вызовы after в обратном порядке.

Если цепочка обратных вызовов была прервана, возвращает false. В противном случае возвращает результат блока, nil, если обратные вызовы не заданы, или true, если обратные вызовы заданы, но блок не передан.

run_callbacks :save do
  save
end

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API