1
votes

I've been following the instructions provided by Cloudinary, but have not been able to get direct uploading working. To further complicate things my image upload is a polymorphic class and is usually in a nested form.

I'm using both the Cloudinary and Carrierwave gems. In the non-direct setup everything works properly however unicorn times out if there are too many images being uploaded at once (which may frequently be the case)

Below is the partial that adds a file upload. It is nested in multiple different forms and the user can add and remove fields dynamically. Per the instructions, I tried to replace = f.file_field :asset and = f.hidden_field :asset_cache with = cl_image_upload :asset, however, this throws an error of: wrong number of arguments (1 for 2..3). When adding a second parameter it is appended to data-cloudinary-field in the generated HTML. Additionally no upload takes place when an image is added and no reference is attached to the record.

_image_fields.html.haml

.image-field-group
  .field
    = f.label :asset, "Image"
    = cl_image_upload :asset
    / = f.file_field :asset
    / = f.hidden_field :asset_cache

  - if f.object && f.object.asset && f.object.asset.filename
    .image-box
      = cl_image_tag(f.object.asset.filename.to_s, :transformation => 'hint', alt: f.object.asset.filename.to_s)

  .remove-fields
    = link_to_remove_fields f

Here are the associated files:

image.rb

class Image < ActiveRecord::Base
  default_scope order('images.id ASC')

  attr_accessible               :asset,
                                :asset_cache

  belongs_to                    :imageable, polymorphic: true

  mount_uploader                :asset, ImageUploader
end

image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base
  include Cloudinary::CarrierWave

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

EDIT: Added Images Controller

images_controller.rb

class ImagesController < ApplicationController
  before_filter :load_imageable

  def index
    @images = @imageable.images
  end

  def new
    @image = @imageable.images.new
  end

  def create
    @image = @imageable.images.new(params[:image])
    if @image.save
      redirect_to @imageable, notice: "Image created."
    else
      render :new
    end
  end

private

  def load_imageable
    resource, id = request.path.split('/')[1, 2]
    @imageable = resource.singularize.classify.constantize.find(id)
  end
end
1
I took a look at this and this but wasn't able to figure it out.Eric Norcross
I also double checked and the jQuery plugin appears to be loading. I added it via application.js //= require cloudinaryEric Norcross
All I needed to do was add f. in front of the cl_image_upload helper. Thus f.cl_image_upload :asset is now working for me.Eric Norcross

1 Answers

1
votes

The following documentation section describes how to use direct image uploading from the browser in your Ruby on Rails application. Make sure to include jQuery and the required plugins in the correct order and to add the required Javascript configuration.

http://cloudinary.com/documentation/rails_image_upload#direct_uploading_from_the_browser

Embedding a file input field that performs direct image uploading is done using the cl_image_upload_tag helper method that accepts the name of the input field.

When using CarrierWave, you can use the cl_image_upload helper method. When calling this method directly, you need to pass the object name and the attribute them (as you do with other Rails view helper methods such as text_field_tag and text_field). Alternatively, you can use it with Rails' standard form builders. Assuming your model is called entity and your attribute with a mounted CarrierWaver uploader is called asset, the following view code should embed a signed file input field for direct uploading from the browser:

= form_for(:entity) do |f|
  = f.cl_image_upload(:asset)

In addition, as you can see below you can use present? to check if the asset exists and pass the CarrierWave attribute directly to cl_image_tag. Alternatively, you can use CarrierWave standard versions instead of dynamically building image URLs using cl_image_tag.

- if f.object && f.object.asset.present?
  .image-box
    = cl_image_tag(f.object.asset, :transformation => 'hint', alt: f.object.asset.filename.to_s)

If the file input field was added successfully to your view but no direct uploading is performed, you should verify that there are no Javascript errors in the console and that all jQuery plugins were included correctly.