Skip to content

Instantly share code, notes, and snippets.

@mrk21
Created March 15, 2017 02:09
Show Gist options
  • Save mrk21/88a8956402e43aa86934d70398ae4abe to your computer and use it in GitHub Desktop.
Save mrk21/88a8956402e43aa86934d70398ae4abe to your computer and use it in GitHub Desktop.
Paperclip stored Redis
# @see https://gist.github.com/basgys/5712426#gistcomment-1274422
class UploadFile
include ActiveModel::Model
include Paperclip::Glue
# Paperclip required callbacks
define_model_callbacks :save, only: [:after]
define_model_callbacks :commit, only: [:after]
define_model_callbacks :destroy, only: [:before, :after]
def self.attributes
[
:id,
:file_file_name,
:file_content_type,
:file_file_size,
:file_updated_at,
:file_fingerprint,
:file_meta,
]
end
attr_accessor *attributes
FinguerPrintHashFunc = Digest::SHA256
has_attached_file :file,
adapter_options: { hash_digest: FinguerPrintHashFunc }
do_not_validate_attachment_file_type :file
class << self
def redis_key(sub_key)
sub_key = sub_key.join(':') if sub_key.is_a? Array
"#{Rails.application.class.parent_name}:#{name}:#{sub_key}"
end
def redis
Redis.current
end
def redis_record_key(id)
redis_key [:record, id]
end
def find(id)
id = redis_record_key(id)
raise ActiveRecord::RecordNotFound, id unless redis.exists(id)
result = redis.hmget(id, attributes)
result = result.map &JSON.method(:load)
result = attributes.zip result
result = Hash[result]
new(result)
end
end
def redis_record_key
self.class.redis_record_key(id)
end
def attributes
self.class.attributes.reduce({}) do |memo, attr|
memo[attr.to_s] = public_send(attr)
memo
end
end
def file_updated_at=(value)
@file_updated_at = Time.zone.parse(value.to_s)
end
def inspect
attrs = attributes.map { |(k, v)| [k, v.inspect].join(': ') }.join(",\n ")
"#<#{self.class.name}:#{object_id} \n #{attrs}>"
end
def new_record?
id.nil?
end
def save
return false unless valid?
run_callbacks :save do
self.id = SecureRandom.uuid if new_record?
attr = attributes.map do |(key, value)|
[key, JSON.dump(value)]
end
self.class.redis.hmset(redis_record_key, *attr.flatten)
self.class.redis.expire(redis_record_key, 10)
end
run_callbacks :commit
true
end
def save!
validate!
save
self
end
def destroy
run_callbacks :destroy do
self.class.redis.del self.redis_record_key
end
run_callbacks :commit
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment