Skip to content

Instantly share code, notes, and snippets.

@djbender
Created March 14, 2019 17:51
Show Gist options
  • Save djbender/760034ff775cffe856749dd54087b5b0 to your computer and use it in GitHub Desktop.
Save djbender/760034ff775cffe856749dd54087b5b0 to your computer and use it in GitHub Desktop.
example of wrapping an ActiveRecord class with a module that uses it so as to separate the behavior of AttachmentUploadStatus from the persistence concerns (and table name) of AttachmentUploadFailures since only failures are stored in the db.
# app/models/attachment_upload_status.rb
module AttachmentUploadStatus # no parent needed!
def self.cache_key(attachment)
"attachment_upload:#{attachment.global_id}:status"
end
def self.pending!(attachment)
Rails.cache.write(cache_key(attachment), 'pending', expires_in: 1.day.from_now)
end
def self.success!(attachment)
Rails.cache.delete(cache_key(attachment))
end
def self.failed!(attachment, error)
attachment.shard.activate do
AttachmentUploadFailure.create!(
attachment: attachment,
error: error
).tap { Rails.cache.delete(cache_key(attachment)) }
end
end
# If Rails.cache has a status, use that. Otherwise check for AttachmentUploadFailure in db.
# If everything is empty, means the upload was a success.
def self.upload_status(attachment)
status = Rails.cache.read(cache_key(attachment))
return status if status
return 'failed' if AttachmentUploadFailure.where(attachment: attachment).exists?
'success'
end
class AttachmentUploadFailure < ApplicationRecord
# I assume this table name would otherwise prepend `attachment_upload_status_` since that's this class's full object name
self.table_name = :attachment_upload_failures
belongs_to :attachment
validates :attachment, :error, presence: true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment