Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Module providing picture storage for given model
- module Picturable
- # Methods that are used in both HasOne and HasMany concerns
- module Shared
- # Method that acts as a direct alias for a picture thumb method
- # @param args [Array] arguments for Dragonfly thumb
- # @return [String] url for given thumb
- def thumb(*args)
- picture.thumb(*args)
- end
- end
- # Include if you want to have multiple pictures for model
- module HasMany
- include Picturable::Shared
- extend ActiveSupport::Concern
- # Orders in which picturable pictures can be sorted when using
- # the ordered scope
- AVAILABLE_PICTURES_ORDERS = [
- 'created_at ASC',
- 'created_at DESC',
- 'image_name ASC',
- 'image_name DESC'
- ]
- included do
- class << self
- attr_accessor :require_pictures
- attr_accessor :main_picture
- # @return [Boolean] should we require pictures
- def require_pictures?
- require_pictures
- end
- end
- self.require_pictures = true
- self.main_picture = :last
- enum pictures_order: AVAILABLE_PICTURES_ORDERS
- delegate :thumb, to: :picture
- has_many :pictures,
- as: :picturable,
- dependent: :destroy
- scope :with_pictures, -> { joins(:pictures).includes(:pictures).distinct }
- default_scope lambda {
- self.require_pictures? ? with_pictures : where(false)
- }
- accepts_nested_attributes_for :pictures,
- allow_destroy: true
- validates :pictures_order,
- presence: true
- validates :pictures,
- length: { minimum: 1 },
- if: -> { self.class.require_pictures? }
- # @return [Picture] first picture that will acts as a cover
- # It simplifies interface - both has one and has many will have
- # a picture method to return a cover
- def picture
- pictures.public_send(self.class.main_picture)
- end
- end
- end
- end
- # Single picture that can be attached to any models
- class Picture < ApplicationRecord
- extend Dragonfly::Model
- dragonfly_accessor :image
- delegate :url, to: :image
- alias_method :to_s, :url
- belongs_to :picturable,
- polymorphic: true,
- counter_cache: true,
- touch: true,
- optional: true
- scope :ordered, lambda {
- return self unless (parent = new.picturable)
- order(parent.pictures_order)
- }
- dragonfly_accessor :image do
- after_assign do |attachment|
- # Auto orient all the images - so they will look as they should
- attachment.convert! '-auto-orient'
- self.aspect_ratio = attachment.aspect_ratio
- end
- end
- # Max size of an image that can be uploaded
- MAX_SIZE = 15.megabytes
- # Available images formats (based on ImageMagick)
- AVAILABLE_FORMATS = %w( jpeg png gif )
- validates :image,
- presence: true
- validates_size_of :image,
- maximum: MAX_SIZE
- validates_property :format,
- of: :image, in: AVAILABLE_FORMATS,
- message: I18n.t('activerecord.errors.models.picture.attributes.image.images_only')
- # Method that acts as a direct alias for an image thumb but with additional
- # formatting handling. There's an issue with gif images - if we want to
- # make jpg thumb out of them, we have to flatten it and convert to png/jpg
- # that's why we check a params format here - if it is not gif, it will flatten
- # a given image
- # @param args [Array] arguments for Dragonfly thumb
- # @return [String] url for given thumb
- def thumb(*args)
- params = args.last.is_a?(Hash) ? args.last : {}
- encode = params[:format] && params[:format] != 'gif'
- if encode
- result = image.encode(params[:format], '-flatten').thumb(*args)
- else
- result = image.thumb(*args)
- end
- # Sometimes this is a Dragonly processor and sometimes it is a direct
- # file link - so we need to check
- result.is_a?(String) ? result : result.url
- end
- end
- # This model represents a single article/news/text etc
- class Text < ApplicationRecord
- include Picturable::HasMany
- validates :title,
- presence: true
- validates :abstract,
- presence: true
- validates :content,
- presence: true
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement