Skip to content

Storage & Files

Justin Coyne edited this page Oct 13, 2017 · 3 revisions

Registering StorageAdapters

There are currently three storage adapters available, and the most common way of using them is to instantiate them and register them with Valkyrie::StorageAdapter via a short-name, for access later.

# Store files on local disk
Valkyrie::StorageAdapter.register(
  Valkyrie::Storage::Disk.new(base_path: '/path/to/files'),
  :disk
)

# Store files in Fedora
Valkyrie::StorageAdapter.register(
  Valkyrie::Storage::Fedora.new(connection: ActiveFedora.fedora.connection),
  :fedora
)

# Store files in memory (for testing)
Valkyrie::StorageAdapter.register(
  Valkyrie::Storage::Memory.new,
  :memory
)

Getting a StorageAdapter instance

Default

To get the default StorageAdapter:

storage = Valkyrie.config.storage_adapter

Named

To get a particular named StorageAdapter, find it by the name it was registered under:

storage = Valkyrie::StorageAdapter.find(:disk)

Uploading a file

Define a resource to attach the file to:

class FileSet < Valkyrie::Resource
  attribute :id, Valkyrie::Types::ID.optional
  attribute :title, Valkyrie::Types::Set
  attribute :file_identifiers, Valkyrie::Types::Set
end

See Persistence & Queries for more info on working with resources.

Upload a file and attach to the resource:

file_set = FileSet.new title: 'page 1'
upload = ActionDispatch::Http::UploadedFile.new tempfile: File.new('/path/to/files/file1.tiff'), filename: 'file1.tiff', type: 'image/tiff'
file = storage.upload(file: upload, resource: file_set)
file_set.file_identifiers << file.id
persister.save(resource: file_set)

Finding a file:

file = storage.find_by(id: 'disk:///path/to/files/file1.tiff')

What can you do with a file?

Get basic file info:

file.id
# => #<Valkyrie::ID:0x007ffa39f8e478 @id="disk:///path/to/files/file1.tiff">

file.size
# => 123456

Read the file's content:

file.read => ruby IO object with the file's content

Calculate and verify checksums:

file.checksum digests: [Digest::SHA1.new, Digest::MD5.new]
# => ["f1d2d2f924e986ac86fdf7b36c94bcdf32beec15", "d3b07384d113edec49eaa6238ad5ff00"]

file.valid? size: 123456, digests: { sha1: 'f1d2d2f924e986ac86fdf7b36c94bcdf32beec15', md5: 'd3b07384d113edec49eaa6238ad5ff00' }
# => true

Caveat

The default file mover is FileUtils.mv. This means the source file will disappear. If you want to copy instead define the source as so:

  Valkyrie::StorageAdapter.register(
    Valkyrie::Storage::Disk.new(
      base_path: Rails.root.join("tmp", "files"),
      file_mover: FileUtils.method(:cp)
    ),
    :disk
)

You may want to consider using fixture_file_upload in tests, as it creates a temporary copy to use.

Clone this wiki locally