module Shrine::ClassMethods

Attributes

logger[RW]

A logger instance.

opts[R]

Generic options for this class, plugins store their options here.

storages[RW]

A hash of storages with their symbol identifiers.

Public Instance Methods

Attachment(name, **args) click to toggle source

Generates an instance of Shrine::Attachment to be included in the model class. Example:

class Photo
  include Shrine::Attachment(:image) # creates a Shrine::Attachment object
end
# File lib/shrine.rb, line 98
def Attachment(name, **args)
  self::Attachment.new(name, **args)
end
Also aliased as: attachment, []
[](name, **args)
Alias for: Attachment
attachment(name, **args)
Alias for: Attachment
deprecation(message) click to toggle source

Prints a deprecation warning to the logger.

# File lib/shrine.rb, line 157
def deprecation(message)
  Shrine.logger.warn "SHRINE DEPRECATION WARNING: #{message}"
end
find_storage(name) click to toggle source

Retrieves the storage under the given identifier (can be a Symbol or a String), raising Shrine::Error if the storage is missing.

# File lib/shrine.rb, line 88
def find_storage(name)
  storages[name.to_sym] || storages[name.to_s] or fail Error, "storage #{name.inspect} isn't registered on #{self}"
end
inherited(subclass) click to toggle source

When inheriting Shrine, copy the instance variables into the subclass, and create subclasses of core classes.

# File lib/shrine.rb, line 48
def inherited(subclass)
  subclass.instance_variable_set(:@opts, deep_dup(opts))
  subclass.instance_variable_set(:@storages, storages.dup)

  file_class = Class.new(self::UploadedFile)
  file_class.shrine_class = subclass
  subclass.const_set(:UploadedFile, file_class)

  attachment_class = Class.new(self::Attachment)
  attachment_class.shrine_class = subclass
  subclass.const_set(:Attachment, attachment_class)

  attacher_class = Class.new(self::Attacher)
  attacher_class.shrine_class = subclass
  subclass.const_set(:Attacher, attacher_class)
end
plugin(plugin, *args, **kwargs, &block) click to toggle source

Load a new plugin into the current class. A plugin can be a module which is used directly, or a symbol representing a registered plugin which will be required and then loaded.

Shrine.plugin MyPlugin
Shrine.plugin :my_plugin
# File lib/shrine.rb, line 71
def plugin(plugin, *args, **kwargs, &block)
  plugin = Plugins.load_plugin(plugin) if plugin.is_a?(Symbol)
  Plugins.load_dependencies(plugin, self, *args, **kwargs, &block)
  self.include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
  self.extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
  self::UploadedFile.include(plugin::FileMethods) if defined?(plugin::FileMethods)
  self::UploadedFile.extend(plugin::FileClassMethods) if defined?(plugin::FileClassMethods)
  self::Attachment.include(plugin::AttachmentMethods) if defined?(plugin::AttachmentMethods)
  self::Attachment.extend(plugin::AttachmentClassMethods) if defined?(plugin::AttachmentClassMethods)
  self::Attacher.include(plugin::AttacherMethods) if defined?(plugin::AttacherMethods)
  self::Attacher.extend(plugin::AttacherClassMethods) if defined?(plugin::AttacherClassMethods)
  Plugins.configure(plugin, self, *args, **kwargs, &block)
  plugin
end
upload(io, storage, **options) click to toggle source

Uploads the file to the specified storage. It delegates to ‘Shrine#upload`.

Shrine.upload(io, :store) #=> #<Shrine::UploadedFile>
# File lib/shrine.rb, line 107
def upload(io, storage, **options)
  new(storage).upload(io, **options)
end
uploaded_file(object) click to toggle source

Instantiates a Shrine::UploadedFile from a hash, and optionally yields the returned object.

data = { "storage" => "cache", "id" => "abc123.jpg", "metadata" => {} }
Shrine.uploaded_file(data) #=> #<Shrine::UploadedFile>
# File lib/shrine.rb, line 116
def uploaded_file(object)
  case object
  when String
    uploaded_file(JSON.parse(object))
  when Hash
    object = JSON.parse(object.to_json) if object.keys.grep(Symbol).any? # deep stringify keys
    self::UploadedFile.new(object)
  when self::UploadedFile
    object
  else
    fail ArgumentError, "cannot convert #{object.inspect} to a #{self}::UploadedFile"
  end
end
warn(message) click to toggle source

Prints a warning to the logger.

# File lib/shrine.rb, line 152
def warn(message)
  Shrine.logger.warn "SHRINE WARNING: #{message}"
end
with_file(io) { |io| ... } click to toggle source

Temporarily converts an IO-like object into a file. If the input IO object is already a file, it simply yields it to the block, otherwise it copies IO content into a Tempfile object which is then yielded and afterwards deleted.

Shrine.with_file(io) { |file| file.path }
# File lib/shrine.rb, line 136
def with_file(io)
  if io.respond_to?(:path)
    yield io
  elsif io.is_a?(UploadedFile)
    io.download { |tempfile| yield tempfile }
  else
    Tempfile.create("shrine-file", binmode: true) do |file|
      IO.copy_stream(io, file.path)
      io.rewind

      yield file
    end
  end
end

Private Instance Methods

deep_dup(collection) click to toggle source

Deep duplicates a nested hash of options.

# File lib/shrine.rb, line 164
def deep_dup(collection)
  duplicate_collection = collection.dup

  if duplicate_collection.is_a?(Hash)
    duplicate_collection.each do |key, value|
      duplicate_collection[key] = deep_dup(value) if value.is_a?(Enumerable)
    end
  end

  duplicate_collection
end