module Coverable extend ActiveSupport::Concern COVER_IMAGE_TYPES = %w[image/png image/jpeg image/webp].freeze MAX_COVER_BYTES = 5.megabytes included do has_one_attached :cover_image has_one_attached :cover_slate validate :cover_image_file_type, if: -> { cover_image.attached? && cover_image.blob&.new_record? } validate :cover_image_file_size, if: -> { cover_image.attached? && cover_image.blob&.new_record? } end def cover_image_attached? cover_image.attached? end def cover_url return unless cover_image.attached? Rails.application.routes.url_helpers.rails_blob_path(cover_image, only_path: true) end def effective_cover_url if cover_image.attached? cover_url else cover_parent&.effective_cover_url end end private def cover_parent nil end def cover_image_file_type return if cover_image.content_type.in?(COVER_IMAGE_TYPES) errors.add(:cover_image, I18n.t("coverable.errors.invalid_type")) end def cover_image_file_size return if cover_image.byte_size <= MAX_COVER_BYTES errors.add(:cover_image, I18n.t("coverable.errors.too_large")) end end