In my Rails 3 application I have multiple models, and each model is associated with another model.
User
model
has_many :departments
accepts_nested_attributes_for :departments
Department
Model
has_many :projects
accepts_nested_attributes_for :projects
I am trying to insert data through the postman REST client using JSON. I have found some of the formats except there is an image upload field in the User
model that I am going to handle with the PaperClip
gem.
Through my rails view it is working fine, but how do I upload an image using postman?
For uploading through REST client I need the JSON format equivalent of my image.
Is there any way to embed the image in json so I can use the postman rest client?
What is Base64
When you have some binary data that you want to ship across a network, you generally don't do it by just streaming the bits and bytes over the wire in a raw format. Why? because some media are made for streaming text. You never know -- some protocols may interpret your binary data as control characters (like a modem), or your binary data could be screwed up because the underlying protocol might think that you've entered a special character combination (like how FTP translates line endings).So to get around this, people encode the binary data into characters. Base64 is one of these types of encodings. Why 64? Because you can generally rely on the same 64 characters being present in many character sets, and you can be reasonably confident that your data's going to end up on the other side of the wire uncorrupted.
-- Taken from What is base 64 encoding used for?
So one way of doing it is to put a Base64 string inside your json request and have your app decode it.
# Your request
{
'user':{
# ....
'picture':'GIF89a\xB4\x00\x1F\x00\xE7\xFD....'
}
}
Here is what your model could do
class User < ActiveRecord::Base
def convert_from_base64(image_data)
data = StringIO.new(Base64.decode64(image_data))
data.class.class_eval { attr_accessor :original_filename, :content_type }
tmp = Tempfile.new("base64")
tmp.write(data.read)
tmp.close
# only on *nix
data.content_type = IO.popen(["file", "--brief", "--mime-type",tmp.path],
in: :close, err: :close).read.chomp
data.original_filename = "picture." + data.content_type.split("/").last
data
end
end
# in your controller
def create
image_data = JSON.parse(params[:json])['user']['picture'] #or which ever field it is
params[:user][:picture] = @user.convert_from_base64(image_data)
# ....
end
But a quick look at POSTMAN tells me you have to do the encoding your self.
Alternatively
you can just pass a url instead of the data - if the url is pointing to resource available on the net.
require "open-uri"
class User < ActiveRecord::Base
def picture_from_url(url)
self.picture = open(url)
end
end
# then just do
user.picture_from_url params[:user][:photo_url]
Update
Postman actually allows you to construct a post request with an image attached. Isnt that what you are looking for ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With