70 lines
1.8 KiB
Ruby
70 lines
1.8 KiB
Ruby
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
|