uploading file with grape and paperclip
Asked Answered
E

4

7

I'm working on a REST API, trying to upload a picture of user with:

  • grape micro-framework
  • paperclip gem but it's not working, showing this error
  • rails version is 3.2.8

No handler found for #<Hashie::Mash filename="user.png" head="Content-Disposition: form-data; name=\"picture\"; filename=\"user.png\"\r\nContent-Type: image/png\r\n" name="picture" tempfile=#<File:/var/folders/7g/b_rgx2c909vf8dpk2v00r7r80000gn/T/RackMultipart20121228-52105-43ered> type="image/png">

I tried testing paperclip with a controller and it worked but when I try to upload via grape api its not working my post header is multipart/form-data

My code for the upload is this

 user = User.find(20) 
 user.picture = params[:picture] 
 user.save! 

So if it is not possible to upload files via grape is there any alternative way to upload files via REST api?

Ebenezer answered 28/12, 2012 at 9:13 Comment(0)
B
17

@ahmad-sherif solution works but you loose original_filename (and extension) and that can provide probems with preprocessors and validators. You can use ActionDispatch::Http::UploadedFile like this:

  desc "Update image"
  params do
    requires :id, :type => String, :desc => "ID."
    requires :image, :type => Rack::Multipart::UploadedFile, :desc => "Image file."
  end
  post :image do
    new_file = ActionDispatch::Http::UploadedFile.new(params[:image])
    object = SomeObject.find(params[:id])
    object.image = new_file
    object.save
  end
Briggs answered 24/6, 2013 at 12:46 Comment(3)
easy and worked like charm with carrierwave as well!Outreach
how do you do to get tempfile=#<File:/var/folders/7g/b_rgx2c909vf8dpk2v00r7r80000gn/T/RackMultipart20121228-52105-43ered> in hashie mash? I get a string, therefore when trying to do new_file I got undefined method `unpack' for nil:NilClassThorson
#<Hashie::Mash content_type="image/jpeg" filename="10665246_10152465972600958_7070250376237090199_n.jpg" tempfile="#<File:0xb603517c>">Thorson
T
8

Maybe a more consistent way to do this would be to define paperclip adapter for Hashie::Mash

module Paperclip
  class HashieMashUploadedFileAdapter < AbstractAdapter

    def initialize(target)
      @tempfile, @content_type, @size = target.tempfile, target.type, target.tempfile.size
      self.original_filename = target.filename
    end

  end
end

Paperclip.io_adapters.register Paperclip::HashieMashUploadedFileAdapter do |target|
  target.is_a? Hashie::Mash
end

and use it "transparently"

 user = User.find(20) 
 user.picture = params[:picture] 
 user.save! 

added to wiki - https://github.com/intridea/grape/wiki/Uploaded-file-and-paperclip

Tejada answered 16/11, 2013 at 1:35 Comment(3)
Where exactly do we put this?Annis
it depends. you can put this code to config/initializers/paperclip_hashie_mash_adapter.rb for the grape on rails. or use smth similar for grape on rake: put it to lib/paperclip_hashie_mash_adapter.rb and require it after app dependencies loaded but before application starts (config/application.rb for example)Tejada
Thanks, that was helpful. I'm using Grape mounted on Rails so I just created an initializer.Annis
R
2

You can pass the File object you got in params[:picture][:tempfile] as Paperclip got an adapter for File objects, like this

user.picture = params[:picture][:tempfile]
user.picture_file_name = params[:picture][:filename] # Preserve the original file name
Refulgent answered 28/12, 2012 at 12:49 Comment(1)
This didn't work: #15355199Lafayette
N
0

For the sake of Rails 5.1 users this should do as well:

/your/endpoint/path

params do
  required :avata, type: File
end

users_spec.rb

describe 'PATCH /users:id' do
  subject { patch "/api/users/#{user.id}", params: params }

  let(:user) { create(:user) }
  let(:params) do
    {
      avatar: fixture_file_upload("spec/fixtures/files/jpg.jpg", 'image/jpeg')
    }
  end

  it 'updates the user' do
    subject      
    updated_user = user.reload
    expect(updated_user.avatar.url).to eq(params[:avatar])
  end
end
Northumbrian answered 31/12, 2018 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.