Skip to content

Instantly share code, notes, and snippets.

@mr4torr
Last active March 18, 2019 22:28
Show Gist options
  • Save mr4torr/1487e6bf19985b6f7b7c4b32977416e8 to your computer and use it in GitHub Desktop.
Save mr4torr/1487e6bf19985b6f7b7c4b32977416e8 to your computer and use it in GitHub Desktop.
Simple Form: input with preview image / Concern per paperclip = seo friendly and easy remove file
#
# save file: app/models/concerns/attachment_concern.rb
#
# Example:
# -------------------------------------
# add Model ------------
# has_attached_file :picture, styles: {
# medium: "600x315#",
# thumb: "160x160>"
# }
# include AttachmentConcern
#
#
# add Controller ---------
# def permitted_params
# params.permit(page: [ :picture, :remove_picture, ...]
# end
#
# Install image_preview_input.rb to make it easier to preview the image in the input, along with checkbox for deletion
# https://gist.github.com/mr4torr/1487e6bf19985b6f7b7c4b32977416e8
module AttachmentConcern
extend ActiveSupport::Concern
included do |base = nil, &block|
attachments_keys = attachment_definitions.keys
attachment_definitions.each do |key, val|
attr_accessor :"remove_#{key}"
before_validation { send(key).clear if send("remove_#{key}") == '1' }
before_update { send(:new_name_attached, attachments_keys) }
after_update { send(:new_filename_attached, attachments_keys) }
define_method :"remove_#{key}=" do |value|
instance_variable_set :"@remove_#{key}", value
send("#{key}_file_name_will_change!")
end
content_type = val[:content_type] || Constant::CONTENT_TYPE_UPLOAD
content_size = val[:content_size] || Constant::SIZE_UPLOAD
validates key.to_sym, attachment_size: { in: content_size },
attachment_content_type: { content_type: content_type }
end
def new_name_attached(attachments = [])
return if self.try(:name) && !name_changed?
return if self.try(:title) && !title_changed?
get_name = self.try(:name) || self.try(:title)
attachments.each do |key|
_file_name = (key.to_s+"_file_name").to_sym
_filename = self.send(key)
_extension = Paperclip::Interpolations.extension(_filename, :original)
self[_file_name] = get_name.parameterize + '.' + _extension
end
end
def new_filename_attached(attachments = [])
return if self.try(:name) && !name_changed?
return if self.try(:title) && !title_changed?
get_name_was = title_was if self.try(:title)
get_name_was = name_was if self.try(:name)
attachments.each do |key|
_file_name = (key.to_s+"_file_name").to_sym
_filename = self.send(key)
_name = Paperclip::Interpolations.param(_filename, :original)
_extension = Paperclip::Interpolations.extension(_filename, :original)
_old_name = get_name_was.parameterize + '.' + _extension
_new_name = _name + '.' + _extension
(_filename.styles.keys+[:original]).each do |style|
begin
new_path = self.send(key).path(style)
old_path = new_path.gsub(_new_name, _old_name)
File.rename(old_path, new_path)
rescue
nil
end
end
end
end
end
end
#
# Install:
# -------------------------------------
# save file: app/inputs/image_preview_input.rb
# add file: config/application.rb ( config.autoload_paths += Dir[Rails.root.join('app', 'inputs').to_s] )
#
# Example:
# -------------------------------------
#
# add View ------------
# <%= form.input :picture, as: :image_preview %>
#
# -- params optional
# <%= form.input :picture, as: :image_preview, input_html: { preview_version: :thumb, preview_width: 50, preview_height: 50 } %>
#
#
# Install attachment_concern.rb to make it easier to delete with paperclip
# https://gist.github.com/mr4torr/1487e6bf19985b6f7b7c4b32977416e8
#
class ImagePreviewInput < SimpleForm::Inputs::FileInput
def hint(wrapper_options = nil)
end
def input(wrapper_options)
version = input_html_options[:preview_version].present? ? input_html_options.delete(:preview_version) : :thumb
preview_width = input_html_options[:preview_width].present? ? input_html_options.delete(:preview_width) : nil
preview_height = input_html_options[:preview_height].present? ? input_html_options.delete(:preview_height) : nil
out = ActiveSupport::SafeBuffer.new
if object.send("#{attribute_name}?")
image_src = object.send(attribute_name).tap do |o|
break o.url(version) if version
end
out << '<div class="d-block">'.html_safe
out << template.image_tag(image_src, width: preview_width, height: preview_height)
out << @builder.input("remove_#{attribute_name}", as: :boolean, :label => I18n.t('views.is_delete'))
out << '</div>'.html_safe
end
input_html_options.merge!({ wrapper: :custom_file, label: I18n.t('views.send_file') })
out << @builder.input(attribute_name, input_html_options)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment