Spec-Zone.ru › Ruby on Rails 6.0

модуль ActiveSupport::Callbacks

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

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

По умолчанию обработчики останавливаются, выбросив :abort. Подробности см. в ClassMethods.define_callbacks.

Поддерживаются три вида обработчиков: обработчики до события, запускаемые перед событием; обработчики после события, запускаемые после события; и обработчики вокруг события, блоки, которые окружают событие, вызывая его при 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) { || ... } Показать исходный код
# File activesupport/lib/active_support/callbacks.rb, line 97
def run_callbacks(kind)
  callbacks = __callbacks[kind.to_sym]

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

    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 && skipped.first
        break env.value
      end
    end

    # 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.call
    end
  end
end

Выполняет обработчики для данного события.

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

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

run_callbacks :save do
  save
end

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

Spec-Zone.ru

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