app/services/library_event_service.rb
# Takes a dirtied LibraryEntry and generates a list of LibraryEvents for the changes
class LibraryEventService
# The change values to store in the event
CHANGES_FOR_EVENT = {
rated: %w[rating],
progressed: %w[progress reconsume_count volumes_owned time_spent],
updated: %w[status reconsume_count],
reacted: %w[media_reaction_id],
annotated: %w[notes]
}.freeze
# @param library_entry [LibraryEntry] the dirty LibraryEntry to figure out events for
def initialize(entry)
@entry = entry
end
# @return [Array<LibraryEvent>] a list of (unsaved) LibraryEvents generated by this changeset
def events
return [] if @entry.imported
[rated_event, progressed_event, updated_event, reacted_event, annotated_event].compact!
end
def create_events!
LibraryEvent.transaction { events.map(&:save!) }
end
private
def rated_event
event_for(:rated) if @entry.saved_change_to_rating?
end
def progressed_event
if @entry.saved_change_to_progress? || @entry.saved_change_to_reconsume_count? ||
@entry.saved_change_to_volumes_owned?
event_for(:progressed)
end
end
def updated_event
event_for(:updated) if @entry.saved_change_to_status?
end
def reacted_event
event_for(:reacted) if @entry.saved_change_to_media_reaction_id?
end
def annotated_event
event_for(:annotated) if @entry.saved_change_to_notes?
end
def event_for(kind)
LibraryEvent.new(
kind: kind,
changed_data: @entry.saved_changes.slice(*CHANGES_FOR_EVENT[kind]),
library_entry_id: @entry.id,
anime_id: @entry.anime_id,
manga_id: @entry.manga_id,
drama_id: @entry.drama_id,
user_id: @entry.user_id
)
end
end