# frozen_string_literal: true module AasmEventsConcern extend ActiveSupport::Concern included do # Todos los eventos de la máquina de estados # # @return [Array] def self.events aasm.events.map(&:name) - self::IGNORED_EVENTS end # Encuentra todos los eventos que se pueden ejecutar con el filtro # actual. # # @return [Array] def self.transitionable_events(current_state) self.events.select do |event| aasm.events.find { |x| x.name == event }.transitions_from_state? current_state end end # Todos los estados de la máquina de estados # # @return [Array] def self.states aasm.states.map(&:name) - self::IGNORED_STATES end # Define un método que cambia el estado para todos los objetos del # scope actual. # # @return [Bool] Si hubo al menos un error, devuelve false. self.aasm.events.map(&:name).each do |event| define_singleton_method(:"#{event}_all!") do success = true self.find_each do |object| object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?") rescue Exception => e success = false notify_exception! e, object end success end # Ejecuta la transición del evento en la base de datos sin # ejecutar los callbacks, sin modificar los items del scope que no # pueden transicionar. # # @return [Integer] Registros modificados define_singleton_method(:"#{event}_all_without_callbacks!") do aasm_event = self.aasm.events.find { |e| e.name == event } to_state = aasm_event.transitions.map(&:to).first from_states = aasm_event.transitions.map(&:from) self.unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state, updated_at: Time.now) end end # Envía notificación de errores # # @param exception [Exception] # @param record [ApplicationRecord] def self.notify_exception!(exception, record) ExceptionNotifier.notify_exception(exception, data: { record_type: record.class.name, record_id: record.id }) end end end