Data stores
Data stores are key-value stores that store a piece of content with meta (the value) and reference it with a string uid (the key).
Dragonfly uses these to store data which can later be fetched, e.g.
Given any Dragonfly job
job = Dragonfly.app.generate(:text, "lublug").thumb('x200')
it can be stored with
uid = job.store # ===> "2013/11/06/12_38_39_606_taj.jpg"
and later fetched with
Dragonfly.fetch(uid)
Models
Models simply hold a reference to the uid and do the storing and fetching behind the scenes at the appropriate times - see Models for more details.
File data store
This is the default, but it can be manually configured using
Dragonfly.app.configure do
datastore :file
# ...
end
or with options
datastore :file,
:root_path => 'public/dragonfly', # directory under which to store files
# - defaults to 'dragonfly' relative to current dir
:server_root => 'public' # root for urls when serving directly from datastore
# using remote_url
You can specify the storage path per-content with
uid = job.store(:path => 'my/custom/path')
To see how to do this with models, see Models - Storage Options
Memory data store
The Memory data store keeps everything in memory and is useful for things like tests.
To use:
Dragonfly.app.configure do
datastore :memory
# ...
end
You can also specify the uid on store
uid = job.store(:uid => "179")
Other data stores
The following datastores previously in Dragonfly core are now in separate gems:
Building a custom data store
Data stores need to implement three methods: write
, read
and destroy
.
class MyDataStore
# Store the data AND meta, and return a unique string uid
def write(content, opts={})
some_unique_uid = SomeLibrary.store(content.data, meta: content.meta)
some_unique_uid
end
# Retrieve the data and meta as a 2-item array
def read(uid)
data = SomeLibrary.get(uid)
meta = SomeLibrary.get_meta(uid)
if content
[
data, # can be a String, File, Pathname, Tempfile
meta # the same meta Hash that was stored with write
]
else
nil # return nil if not found
end
end
def destroy(uid)
SomeLibrary.delete(uid)
end
end
The above should be fairly self-explanatory, but to be a bit more specific:
write
- takes a content object (see Dragonfly::Content for more details) and uses a method like
data
(String),file
,path
to get its data andmeta
to get its meta - also takes an options hash, passing through any options passed to
store
- returns a unique String uid
read
- takes a String uid
- returns a 2-item array; the data in the form of a String, Pathname, File or Tempfile and the meta hash
- returns nil instead if not found
destroy
- takes a String uid
- destroys the content
You can also optionally serve data directly from the datastore using
Dragonfly.app.remote_url_for(uid)
or
my_model.attachment.remote_url
provided the data store implements url_for
class MyDataStore
# ...
def url_for(uid, opts={})
"http://some.domain/#{uid}"
end
end
Both remote_url_for
and remote_url
also take an options hash which will be passed through to the data store’s url_for
method.
Using your custom data store
Your custom data store can be used by a Dragonfly app with
Dragonfly.app.configure do
datastore MyDataStore.new(:some => 'args')
# ...
end
or you can register a symbol (which you may want to do if creating a gem)
Dragonfly::App.register_datastore(:my_data_store){ MyDataStore }
so you configure using just the symbol
Dragonfly.app.configure do
datastore :my_data_store, :some => 'args'
# ...
end
Note that the data store class is registered with the symbol, not the instance. Any other args are passed straight to the data store’s initialize
method.
Testing with RSpec
Dragonfly provides a shared rspec example group that you can use to test that your custom data store conforms to the basic spec. Here’s a simple example spec file
require 'spec_helper'
require 'dragonfly/spec/data_store_examples'
describe MyDataStore do
before(:each) do
@data_store = MyDataStore.new
end
it_should_behave_like 'data_store'
end
Derived from theme by orderedlist