Skip to content

Instantly share code, notes, and snippets.

@janko
Last active September 5, 2022 23:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save janko/8ba5fca80719101ac91d744890e5075b to your computer and use it in GitHub Desktop.
Save janko/8ba5fca80719101ac91d744890e5075b to your computer and use it in GitHub Desktop.
Workaround for embedded documents in shrine-mongoid
require "mongoid"
require "shrine"
require "shrine/storage/memory"
require "stringio"
Mongoid.configure do |config|
config.clients.default = { hosts: ['localhost:27017'], database: 'my_db' }
config.log_level = :debug
end
Shrine.storages = {
cache: Shrine::Storage::Memory.new,
store: Shrine::Storage::Memory.new,
}
Shrine.plugin :mongoid
module EmbeddedMongoidSupport
module AttacherClassMethods
def load_record(data)
if data["parent"]
parent_class, parent_id, association_name = data["parent"]
child_class, child_id = data["record"]
parent_class = Object.const_get(parent_class)
parent = find_record(parent_class, parent_id)
association = parent.send(association_name)
association.where(id: child_id).first
else
super
end
end
end
module AttacherMethods
def dump
hash = super
if record.embedded?
hash["parent"] = [
record._parent.class.to_s,
record._parent.id.to_s,
record.association_name.to_s
]
end
hash
end
def swap(new_file)
if record.embedded?
association = record._parent.send(record.association_name)
reloaded = association.where(id: record.id).first
return if reloaded.nil? || self.class.new(reloaded, name).read != read
update(new_file)
else
super
end
end
end
end
class ImageUploader < Shrine
plugin :backgrounding
plugin EmbeddedMongoidSupport
Attacher.promote { |data| self.class.promote(data) } # mimic background job
end
class Album
include Mongoid::Document
embeds_many :photos
end
class Photo
include Mongoid::Document
include ImageUploader::Attachment.new(:image)
embedded_in :album
field :image_data, type: String
end
album = Album.create
photo = album.photos.create(image: StringIO.new)
photo = album.reload.photos.first
photo.image # => #<ImageUploader::UploadedFile:0x00007f894e14fbc0 @data={"id"=>"c43279e81ccc51d6743a884ea9bd34b1", "storage"=>"store", "metadata"=>{"filename"=>nil, "size"=>0, "mime_type"=>nil}}>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment