lib/refile/rails/attachment_helper.rb in refile-0.4.2 vs lib/refile/rails/attachment_helper.rb in refile-0.5.0
- old
+ new
@@ -1,22 +1,71 @@
module Refile
+ # Rails view helpers which aid in using Refile from views.
module AttachmentHelper
+ # Form builder extension
+ module FormBuilder
+ # @see AttachmentHelper#attachment_field
+ def attachment_field(method, options = {})
+ self.multipart = true
+ @template.attachment_field(@object_name, method, objectify_options(options))
+ end
+ end
+
+ # View helper which generates a url for an attachment. This generates a URL
+ # to the {Refile::App} which is assumed to be mounted in the Rails
+ # application.
+ #
+ # Optionally the name of a processor and a arguments to it can be appended.
+ #
+ # If the filename option is not given, the filename falls back to the
+ # `name`.
+ #
+ # The host defaults to {Refile.host}, which is useful for serving all
+ # attachments from a CDN. You can also override the host via the `host`
+ # option.
+ #
+ # Returns `nil` if there is no file attached.
+ #
+ # @example
+ # attachment_url(@post, :document)
+ #
+ # @example With processor
+ # attachment_url(@post, :image, :fill, 300, 300, format: "jpg")
+ #
+ # @param [Refile::Attachment] record Instance of a class which has an attached file
+ # @param [Symbol] name The name of the attachment column
+ # @param [String, nil] filename The filename to be appended to the URL
+ # @param [String, nil] format A file extension to be appended to the URL
+ # @param [String, nil] host Override the host
+ # @return [String, nil] The generated URL
def attachment_url(record, name, *args, filename: nil, format: nil, host: nil)
- file = record.send(name)
+ attacher = record.send(:"#{name}_attacher")
+ file = attacher.get
return unless file
- filename ||= name.to_s
+ filename ||= attacher.basename || name.to_s
+ format ||= attacher.extension
backend_name = Refile.backends.key(file.backend)
host = host || Refile.host || request.base_url
filename = filename.parameterize("_")
filename << "." << format.to_s if format
::File.join(host, main_app.refile_app_path, backend_name, *args.map(&:to_s), file.id.to_s, filename)
end
+ # Generates an image tag for the given attachment, adding appropriate
+ # classes and optionally falling back to the given fallback image if there
+ # is no file attached.
+ #
+ # Returns `nil` if there is no file attached and no fallback specified.
+ #
+ # @param [String] fallback The path to an image asset to be used as a fallback
+ # @param [Hash] options Additional options for the image tag
+ # @see #attachment_url
+ # @return [ActiveSupport::SafeBuffer, nil] The generated image tag
def attachment_image_tag(record, name, *args, fallback: nil, format: nil, host: nil, **options)
file = record.send(name)
classes = ["attachment", record.class.model_name.singular, name, *options[:class]]
if file
@@ -25,31 +74,40 @@
classes << "fallback"
image_tag(fallback, options.merge(class: classes))
end
end
- # @ignore
- # rubocop:disable Metrics/AbcSize
- def attachment_field(object_name, method, options = {})
+ # Generates a form field which can be used with records which have
+ # attachments. This will generate both a file field as well as a hidden
+ # field which tracks the id of the file in the cache before it is
+ # permanently stored.
+ #
+ # @param object_name The name of the object to generate a field for
+ # @param method The name of the field
+ # @param [Hash] options
+ # @option options [Object] object Set by the form builder, currently required for direct/presigned uploads to work.
+ # @option options [Boolean] direct If set to true, adds the appropriate data attributes for direct uploads with refile.js.
+ # @option options [Boolean] presign If set to true, adds the appropriate data attributes for presigned uploads with refile.js.
+ # @return [ActiveSupport::SafeBuffer] The generated form field
+ def attachment_field(object_name, method, object:, **options)
options[:data] ||= {}
- if options[:object]
- attacher = options[:object].send(:"#{method}_attacher")
- options[:accept] = attacher.accept
+ attacher = object.send(:"#{method}_attacher")
+ options[:accept] = attacher.accept
- if options[:direct]
- host = options[:host] || Refile.host || request.base_url
- backend_name = Refile.backends.key(attacher.cache)
+ if options[:direct]
+ host = options[:host] || Refile.host || request.base_url
+ backend_name = Refile.backends.key(attacher.cache)
- url = ::File.join(host, main_app.refile_app_path, backend_name)
- options[:data].merge!(direct: true, as: "file", url: url)
- end
+ url = ::File.join(host, main_app.refile_app_path, backend_name)
+ options[:data].merge!(direct: true, as: "file", url: url)
+ end
- if options[:presigned] and attacher.cache.respond_to?(:presign)
- options[:data].merge!(direct: true).merge!(attacher.cache.presign.as_json)
- end
+ if options[:presigned] and attacher.cache.respond_to?(:presign)
+ options[:data].merge!(direct: true).merge!(attacher.cache.presign.as_json)
end
- hidden_field(object_name, :"#{method}_cache_id", options.slice(:object)) +
- file_field(object_name, method, options)
+
+ html = hidden_field(object_name, method, value: attacher.data.to_json, object: object)
+ html + file_field(object_name, method, options)
end
end
end