module AvatarsForRails module Avatarable extend ActiveSupport::Concern included do attr_accessor :logo_crop, :logo_crop_x, :logo_crop_y, :logo_crop_w, :logo_crop_h, :avatar_tmp_basename has_attached_file :logo, avatarable_options before_validation :validate_crop_params, :crop_avatar, :check_avatar_aspect_ratio end def avatar_tmp_public_path(root_path) return unless avatar_tmp_file? File.join(root_path, AvatarsForRails.public_tmp_path, @avatar_tmp_basename) end private def avatar_tmp_file? avatar_tmp_basename.present? && File.exists?(avatar_tmp_full_path) end def check_avatar_aspect_ratio return if logo.queued_for_write[:original].blank? FileUtils.cp logo.queued_for_write[:original].path, AvatarsForRails.tmp_path @avatar_tmp_basename = File.basename(logo.queued_for_write[:original].path) dimensions = avatar_tmp_file_dimensions return if dimensions.first == dimensions.last errors.add :logo_crop end def validate_crop_params return if logo_crop_x.blank? %w( x y w h ).each do |attr| send "logo_crop_#{ attr }=", send("logo_crop_#{ attr }").to_f end if logo_crop_w == 0 errors.add(:logo_crop_w, 'avatar.error.no_width') end end def crop_avatar return unless avatar_tmp_file? width, height = avatar_tmp_file_dimensions avatar_magick_image.crop!(logo_crop_x * width, logo_crop_y * height, logo_crop_w * width, logo_crop_h * height) avatar_magick_image.write(avatar_tmp_full_path) self.logo = File.open(avatar_tmp_full_path) FileUtils.remove_file(avatar_tmp_full_path) end def avatar_tmp_full_path return if avatar_tmp_basename.blank? AvatarsForRails.tmp_path avatar_tmp_basename end def avatar_tmp_file_dimensions [ avatar_magick_image.columns, avatar_magick_image.rows ] end def avatar_magick_image @avatar_magick_image ||= Magick::Image.read(avatar_tmp_full_path).first end end end