Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 5.2 Rest API + Active Storage - Upload file blob received from an external service

We are receiving a POST call from an external service, which contains the file blob (in Base64 encoding), and some other parameters.

# POST call to /document/:id/document_data
param = {
    file: <base64 encoded file blob>
}

We would want to process the file and upload it to the following model

# MODELS
# document.rb  
class Document < ApplicationRecord
    has_one_attached :file
end
like image 747
anurag Avatar asked Jul 02 '18 08:07

anurag


People also ask

What's new in rails active storage?

The new approach to file uploads | Prograils Update: Rails and Active Storage. The new approach to file uploads Since its first shipping, Active Storage has revolutionized attaching files to Ruby on Rails applications. Learn what it is, how to set it up and use it, as well what's new in Rails Active Storage in 2021!

Is it possible to upload attachments using active storage in rails?

From many years, we are using libraries like Paperclip, CarrierWave, and Shrine to upload attachments for a rails application. But since the deprecation of paperclip in rails 5.2, I think we need to start using the Active Storage.

Where do rails apps store their data?

The files are uploaded to cloud storage services like Amazon S3, Google Cloud Storage or Microsoft Azure Storage and then attached to Active Record objects in the app. This means Rails developers no longer have to use third-party libraries like CarrierWave for example.

What version of Ruby do I need for ActiveStorage?

Before we begin, make sure you have ruby version >= 2.5.0 and Rails version 5.2.0. The ActiveStorage gem is included on Rails 5.2 by default. You can simply check your version: [ If your ruby version is not up to date, you can update it with a ruby version manager like rvm or rbenv.


1 Answers

In the Controller method handling the POST call

# documents_controller.rb - this method handles POST calls on /document/:id/document_data

def document_data

  # Process the file, decode the base64 encoded file
  @decoded_file = Base64.decode64(params["file"])

  @filename = "document_data.pdf"            # this will be used to create a tmpfile and also, while setting the filename to attachment
  @tmp_file = Tempfile.new(@filename)        # When a Tempfile object is garbage collected, or when the Ruby interpreter exits, its associated temporary file is automatically deleted. 
  @tmp_file.binmode                          # This helps writing the file in binary mode.
  @tmp_file.write @decoded_file
  @tmp_file.rewind()

  # We create a new model instance 
  @document = Document.new
  @document.file.attach(io: @tmp_file, filename: @filename) # attach the created in-memory file, using the filename defined above
  @document.save

  @tmp_file.unlink # deletes the temp file
end

Hope this helps.

More about Tempfile can be found here.

like image 108
anurag Avatar answered Oct 20 '22 08:10

anurag