card/lib/card/dirty.rb
class Card
# Special "dirty" handling for significant card fields.
module Dirty
extend ::Card::Dirty::MethodFactory
class << self
def dirty_fields
%i[name db_content trash type_id left_id right_id codename]
end
def dirty_aliases
{ type: :type_id, content: :db_content }
end
def dirty_options
dirty_fields + dirty_aliases.keys
end
end
dirty_fields.each { |field| define_dirty_methods field }
dirty_aliases.each { |k, v| alias_method "#{k}_is_changing?", "#{v}_is_changing?" }
def attribute_before_act attr
if saved_change_to_attribute? attr
attribute_before_last_save attr
elsif will_save_change_to_attribute? attr
mutations_from_database.changed_values[attr]
elsif not_in_callback?
attribute_was attr
else
_read_attribute attr.to_s
end
end
def not_in_callback?
# or in integrate_with_delay stage
mutations_before_last_save.equal?(mutations_from_database)
end
def attribute_is_changing? attr
if not_in_callback?
attribute_changed? attr
else
saved_change_to_attribute?(attr) ||
will_save_change_to_attribute?(attr)
end
end
end
# Even special-er handling for dirty cardnames
module DirtyNames
def name_is_changing?
super || left_id_is_changing? || right_id_is_changing?
end
# def name_before_last_save
# super || dirty_name(left_id_before_last_save, right_id_before_last_save)
# end
def name_before_act
super || dirty_name(left_id_before_act, right_id_before_act)
end
def dirty_name left_id, right_id
return unless left_id.present? && right_id.present?
parts = [left_id, right_id].map { |id| Card.quick_fetch(id)&.name_before_act }
Card::Name[*parts]
end
def lex_before_act
if (old_left_id = left_id_before_act)
[old_left_id, right_id_before_act]
else
name_before_act
end
end
end
end