0

I've been looking for a while at the Cloudinary documentation but can't figure out how to upload multiple files to it using Rails and a html form.

I added Cloudinary support to my Carrierwave ImageUploader

include Cloudinary::CarrierWave

and I added my api-key and secret to config/cloudinary.yml

but what more do I need to change? For now, I kept everything as it was with carrierwave. So my form holds a file field

<%=file_field_tag "images[]", type: :file, multiple: true %>

and then for every image a new picture instance gets created, and every picture instance holds a :image attribute

if params[:images]
     params[:images].each do |image|
           @post.pictures.create(image: image)
     end
end

I kept my ImageUploader more or less default.

class ImageUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave
  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end 
end

When I upload some images, the urls are linking to a cloudinary page, but nothing has been actually uploaded to cloudinary. Can I just add something to the create action of the picture controller to actually upload the image? Something like

def create
   @picture = Picture.new(picture_params)  
   @picture.save
   Cloudinary::Uploader.upload(picture_params)
end
sjbuysse
  • 3,872
  • 7
  • 25
  • 37
  • The line of code where you upload your images would be good to see. You should have something like this: `Cloudinary::Uploader.upload(your_image, auth)` – The F Sep 09 '15 at 08:43
  • Sorry about that, I updated my question, but this line doesn't seem to upload it either – sjbuysse Sep 09 '15 at 08:47
  • You need to define your authorization params, that are needed for `.upload` as a second parameter. You should do that, and use `.upload` where you actually `include Cloudinary::CarrierWave` – The F Sep 09 '15 at 08:48
  • With authorization, do you mean the api key and secret? because that's defined in `config/cloudinary.yml`, so that should be allright. Also, I should I add the `.upload` to my `ImageUploader` then? – sjbuysse Sep 09 '15 at 09:02
  • Yes and yes - this sounds reasonable. feel free to also post some relevant parts of your uploader instead of your file field, which looks fine to me. – The F Sep 09 '15 at 09:11
  • I edited my last post, and added the uploader details – sjbuysse Sep 09 '15 at 09:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89141/discussion-between-sjbuysse-and-the-f). – sjbuysse Sep 09 '15 at 09:21
  • Try using `create!` instead to raise an exception on any errors. Currently they are silently ignored. I'm not as familiar with CarrierWave as Paperclip, but why do you have `storage :file`? In Paperclip, you have to indicate `:storage => :cloudinary`. – Chloe May 15 '17 at 22:38

2 Answers2

0

Depending on the value of image, you could do this:

if params[:images]
  params[:images].each do |image|
    @post.pictures.create(image: image)
  end
  upload_images(@post.pictures)
end

def upload_images(images)
  images.each do |i|
    Cloudinary::Uploader.upload(i)
  end
end
The F
  • 3,647
  • 1
  • 20
  • 28
  • That doesn't work either, here is the contents of `images` when I upload just 1 image. `"images"=>[#, @original_filename="DSC00699.JPG", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"images[]\"; filename=\"DSC00699.JPG\"\r\nContent-Type: image/jpeg\r\n">]` – sjbuysse Sep 09 '15 at 08:55
  • have you tried upload `image.tempfile` or `image.original_filename` instead of just `image`. Remember, you want to upload the file, not the image object. – The F Sep 09 '15 at 09:14
  • I played around a bit, and it's working more or less with this code now. Thanks for all the help The F. I do have one more problem, and that's that the public_id's don't match, but I created a new question for that. http://stackoverflow.com/questions/32493427/public-id-doesnt-match-between-cloudinary-and-carrierwave – sjbuysse Sep 10 '15 at 04:55
  • 1
    There is no need to upload the image manually to Cloudinary. The each loop should be enough. – Tal Lev-Ami Sep 10 '15 at 10:13
0

Here's how it's done in Paperclip.

class Attachment < ApplicationRecord
  if Rails.env == 'production'
    has_attached_file :file, :storage => :cloudinary, :path => ':class/:id/:filename', :cloudinary_resource_type => :raw


class Deal < ApplicationRecord
  has_and_belongs_to_many :attachments, dependent: :destroy
  accepts_nested_attributes_for :images, :attachments, reject_if: :all_blank, allow_destroy: true

  def files=(files)
    files.each do |file|
      attachments.build(file: file)
    end
  end

#controller
def deal_params
  params.require(:deal).permit :name, ...,  photos: [], files: [] 

#view
= form_for([parent, child], html: { multipart: true }) do |f|
  =f.file_field :files, multiple: true, class: 'form-control'
Chloe
  • 25,162
  • 40
  • 190
  • 357