0
votes

I'm trying to make some kind of profile picture upload that works like follow: The user can choose the profile pic that wants to upload from his computer (carrierwave), then he can crop it as he likes with the aspect ratio of a square 1:1, like in Whatsapp (I use carrierwave-crop-on-fly), and finally the cropped picture is uploaded to the cloud via Cloudinary and it is binded to the column "image" of my model "user". I followed cloudinary's tutorial to do the integration

Here's what I've done so far. Here's the uploader binded with cloudinary:

class AvatarUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave
  include CarrierWave::MiniMagick
  process crop: [100, 100]

  def public_id
    model.nombre
  end
end

In the User's model:

class User < ActiveRecord::Base
  mount_uploader :image, AvatarUploader
  ...

In my view where I can change that profile pic:

.well
  .row-fluid
    .span8.offset2
      %p
        .inline-block
          = form_for @user, method: :post, url: change_photo_self_url do |f|
            = f.file_field :image
            .hidden#cropbox= f.cropbox :image, width: 300, height: 300
            = f.submit "Crop", class: "btn btn-success blanco"
            ...

(#cropbox appears when file_field changes, that is, when an image is examined)

Finally, in users_controller

...
    def change_photo
      user = current_user
      user.update_attributes(user_params)
      sign_in(user)
      redirect_to profile_url
    end
    private
      def user_params
        params.require(:user).permit(..., :image)
    end

Everything worked fine without the "cropping" thing. That is to say, I implemented that the user could choose an image an upload it and everything worked fine. But when I added the controls for cropping it crashes. When I pick an image, the cropping surface appears, I can choose it perfectly, but when I click the submit button "Crop", the following error is triggered before even reaching the controller's action:

Rack::QueryParser::ParameterTypeError at /change_photo
expected Hash (got Hash) for param `image'

Here are the params of the call:

#<Rack::QueryParser::Params:0x396f9f0 @limit=65536, @size=5, @params={"image"=>{:filename=>"140.jpg", :type=>"image/jpeg", :name=>"user[image]", :tempfile=>#<Tempfile:C:/Users/josem/AppData/Local/Temp/RackMultipart20171229-7548-15105ol.jpg>, :head=>"Content-Disposition: form-data; name=\"user[image]\"; filename=\"140.jpg\"\r\nContent-Type: image/jpeg\r\n"}}>

I may guess two params with the same name could be a problem but I don't know how to change it to make it work and I don't understand why "expected Hash (got Hash)" is a problem

1

1 Answers

1
votes

While I'm not quite familiar with "carrierwave-crop-on-fly", you may want to consider accomplishing that differently. Cloudinary also offers the out-of-the-box Upload Widget (https://cloudinary.com/documentation/upload_widget), which also supports performing client-side cropping. Here's a basic RoR/CarrierWave/Cloudinary's-Upload-widget sample project you can test out: https://github.com/taragano/Carrierwave_widget

This project currently excludes the cropping feature, but it can be easily added, see the provided documentation page. One of the parameters you can set at the widget is the cropping_aspect_ratio which can be helpful for you.

Also, note that using the widget, the cropping will be done on the client-side, which will both help with quickening the upload and also your server will not need to process the cropping.