# frozen_string_literal: true module Logux module Model class UpdatesDeprecator EVENT = 'logux.insecure_update' class << self def watch(args = {}, &block) new(args).watch(&block) end end def initialize(level: :warn) @level = level end def watch(&block) callback = lambda(&method(:handle_insecure_update)) ActiveSupport::Notifications.subscribed(callback, EVENT, &block) end private # rubocop:disable Naming/UncommunicativeMethodParamName def handle_insecure_update(_, _, _, _, args) model = args[:model] attributes = model.changed.map(&:to_sym) - [:logux_fields_updated_at] insecure_attributes = attributes & model.class.logux_crdt_mapped_attributes return if insecure_attributes.empty? notify_about_insecure_update(insecure_attributes) end # rubocop:enable Naming/UncommunicativeMethodParamName def notify_about_insecure_update(insecure_attributes) pluralized_attributes = 'attribute'.pluralize(insecure_attributes.count) message = <<~TEXT Logux tracked #{pluralized_attributes} (#{insecure_attributes.join(', ')}) should be updated using model.logux.update(...) TEXT case @level when :warn ActiveSupport::Deprecation.warn(message) when :error raise InsecureUpdateError, message end end end end end