Skip to content

Instantly share code, notes, and snippets.

@benwalsh
Created May 27, 2019 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benwalsh/d611608ea9f4ff6e1ec1efd0d3755b37 to your computer and use it in GitHub Desktop.
Save benwalsh/d611608ea9f4ff6e1ec1efd0d3755b37 to your computer and use it in GitHub Desktop.
module ActiveStorage
class Attached
def perform_attachment(attachables)
return yield unless record.class.respond_to?(:attachment_callbacks)
callbacks = record.class.attachment_callbacks[name.to_sym]
return yield unless callbacks
[callbacks[:before]].flatten.each { |cb| record.send(cb, self, [attachables].flatten) if cb }
yield
[callbacks[:after]].flatten.each { |cb| record.send(cb, self, [attachables].flatten) if cb }
end
end
class Attached::Many < Attached
def attach(*attachables)
perform_attachment(attachables.flatten) do
attachables.flatten.map do |attachable|
if record.new_record?
attachments.build(record: record, blob: create_blob_from(attachable))
else
attachments.create!(record: record, blob: create_blob_from(attachable))
end
end
end
end
end
class Attached::One < Attached
def attach(attachable)
perform_attachment(attachable) do
blob_was = blob if attached?
blob = create_blob_from(attachable)
unless blob == blob_was
transaction do
detach
write_attachment build_attachment(blob: blob)
end
blob_was.purge_later if blob_was && dependent == :purge_later
end
end
end
end
end
module ActiveStorageCallbacks
extend ActiveSupport::Concern
included do
cattr_accessor :attachment_callbacks
extend ActiveModel::Callbacks
define_model_callbacks :attach, only: %i[after before]
after_attach -> {}
before_attach -> {}
class << self
def perform_attach(callbacks)
self.attachment_callbacks = callbacks
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment