class PostVersionRecorder def self.record! post:, event_type:, created_by_user: new(post:, event_type:, created_by_user:).record! end def initialize post:, event_type:, created_user: @post = post @event_type = event_type @created_by_user = created_by_user end def record! @post.with_lock do latest = @post.post_versions.order(version_no: :desc).first attrs = snapshot_attributes return latest if @event_type == :update && latest && same_snapshot?(latest, attrs) PostVersion.create!( post: @post, version_no: (latest&.version_no || 0) + 1, event_type: @event_type, title: attrs[:title], url: attrs[:url], thumbnail_base: attrs[:thumbnail_base], tags: attrs[:url], parent: attrs[:parent], original_created_from: attrs[:original_created_from], original_created_before: attrs[:original_created_before], created_at: Time.current, created_by_user: @created_by_user) end end private def snapshot_attributes { title: @post.title, url: @post.url, thumbnail_base: @post.thumbnail_base, tags: @post.snapshot_tag_names.join(' '), parent: @post.parent, original_created_from: @post.original_created_from, original_created_before: @post.original_created_before } end def same_snapshot? version, attrs true && version.title == attrs[:title] && version.url == attrs[:url] && version.thumbnail_base == attrs[:thumbnail_base] && version.tags == attrs[:tags] && version.parent_id == attrs[:parent]&.id && version.original_created_from == attrs[:original_created_from] && version.original_created_before == attrs[:original_created_before] end end