Skip to content

Instantly share code, notes, and snippets.

@sulmanweb
Created May 13, 2018 08:04
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sulmanweb/7dedb33009ff20138f90576c442fc246 to your computer and use it in GitHub Desktop.
Save sulmanweb/7dedb33009ff20138f90576c442fc246 to your computer and use it in GitHub Desktop.
Active Storage as Attachment in Rails API with base64 decoding
json.extract! document, :id, :documentable_type, :documentable_id, :created_at
json.url rails_blob_url(document.doc)
class Document < ApplicationRecord
has_one_attached :doc
belongs_to :documentable, polymorphic: true, optional: true
attr_accessor :doc_contents
attr_accessor :doc_name
after_create :parse_doc
validate :doc_validations, on: :create
def parse_doc
# If directly uploaded
unless self.doc_contents.nil? || self.doc_contents[/(image\/[a-z]{3,4})|(application\/[a-z]{3,4})/] == ''
content_type = self.doc_contents[/(image\/[a-z]{3,4})|(application\/[a-z]{3,4})/]
content_type = content_type[/\b(?!.*\/).*/]
contents = self.doc_contents.sub /data:((image|application)\/.{3,}),/, ''
decoded_data = Base64.decode64(contents)
filename = self.doc_name || 'doc_' + Time.zone.now.to_s + '.' + content_type
File.open("#{Rails.root}/tmp/images/#{filename}", 'wb') do |f|
f.write(decoded_data)
end
self.doc.attach(io: File.open("#{Rails.root}/tmp/images/#{filename}"), filename: filename)
FileUtils.rm("#{Rails.root}/tmp/images/#{filename}")
end
end
private
def doc_validations
if self.doc_contents.nil?
errors.add(:base, I18n.t('errors.documents.file_required'))
end
end
end
class DocumentsController < ApplicationController
before_action :authenticate_user, only: %i[create]
def create
@document = Document.new(document_params)
if @document.save
return success_document_save
else
return error_save @document
end
end
protected
def success_document_save
render status: :created, template: 'documents/show.json.jbuilder'
end
def error_save obj
render status: :unprocessable_entity, json: {errors: obj.errors.full_messages}
end
private
def document_params
params.permit(:doc_contents, :doc_name)
end
end
class CreateDocuments < ActiveRecord::Migration[5.2]
def change
create_table :documents do |t|
t.references :documentable, polymorphic: true, index: true
t.timestamps
end
end
end
en:
errors:
documents:
file_required: "file attachment is required"
content_type: "attachment must be image or pdfs"
json.partial! 'documents/document.json.jbuilder', document: @document
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment