This commit is contained in:
2025-11-07 13:34:32 -08:00
commit 1e8c5a972b
436 changed files with 11000 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
module Leaf::Editable
extend ActiveSupport::Concern
MINIMUM_TIME_BETWEEN_VERSIONS = 10.minutes
included do
has_many :edits, dependent: :delete_all
after_update :record_moved_to_trash, if: :was_trashed?
end
def edit(leafable_params: {}, leaf_params: {})
if record_new_edit?(leafable_params)
update_and_record_edit leaf_params, leafable_params
else
update_without_recording_edit leaf_params, leafable_params
end
end
private
def record_new_edit?(leafable_params)
will_change_leafable?(leafable_params) && last_edit_old?
end
def last_edit_old?
edits.empty? || edits.last.created_at.before?(MINIMUM_TIME_BETWEEN_VERSIONS.ago)
end
def will_change_leafable?(leafable_params)
leafable_params.select do |key, value|
leafable.attributes[key.to_s] != value
end.present?
end
def update_without_recording_edit(leaf_params, leafable_params)
transaction do
leafable.update!(leafable_params)
edits.last&.touch
update! leaf_params
end
end
def update_and_record_edit(leaf_params, leafable_params)
transaction do
new_leafable = dup_leafable_with_attachments leafable
new_leafable.update!(leafable_params)
edits.revision.create!(leafable: leafable)
update! leaf_params.merge(leafable: new_leafable)
end
end
def dup_leafable_with_attachments(leafable)
leafable.dup.tap do |new|
leafable.attachment_reflections.each do |name, _|
new.send(name).attach(leafable.send(name).blob)
end
end
end
def record_moved_to_trash
edits.trash.create!(leafable: leafable)
end
def was_trashed?
trashed? && previous_changes.include?(:status)
end
end