B
B
buurz2014-09-17 12:29:32
Angular
buurz, 2014-09-17 12:29:32

How to upload multiple Carrierwave/angular +rails files via json?

Hi all. The problem is I can not understand how best to pick up several files / pictures.
We have, back-end = RubyOnRails (gem Carrierwave), front-end = angularJs.
I created a directive in Angular, with the help of which I send data to the server via json.

app.directive 'uploadImage', ->
    return{
      restrict: 'A'
      link:(scope,elem)->
        reader = new FileReader()
        reader.onload =(e)->
          scope.iFile = btoa(e.target.result)
          scope.$apply()

        elem.on 'change', ->
          scope.iFile=''
          file = elem[0].files[0]
          scope.iFilesize = file.size
          scope.iFiletype = file.type
          scope.iFilename = file.name
          scope.$apply()
          reader.readAsBinaryString(file)
    }

When placing an order, you can attach a photo / image, the image is first encoded using base64, attached to the rest of the data and sent to the server, where it is decoded and attached again in the form required for carrierwave.
Action Create in TasksController:
def create
    params[:task][:pict] = parse_image_data(params[:iFile]) if params[:iFile]

    @task = Task.new(task_params)
    
    if @task.save
      clean_tempfile
      render_with_protection @task.to_json, {status: :created, location: @task }
    else
      render_with_protection @task.errors.to_json, {status: :unprocessable_entity }
    end
  end


private

def parse_image_data(image_data)
      Rails.logger.info 'decoding now'
      decoded_data = Base64.decode64(image_data) # json parameter set in directive scope
      # create 'file' understandable by Carrierwave
      @data = StringIO.new(decoded_data)
      @tempfile = Tempfile.new('task-image')
      @tempfile.binmode
      @tempfile.write decoded_data
      @tempfile.rewind
   
      ActionDispatch::Http::UploadedFile.new(
        :tempfile => @tempfile,
        :content_type => params[:itype],
        :filename => params[:iname]
      )
    end

I would like to be able to nest multiple images, does anyone know how to do this?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
F
FanKiLL, 2014-09-17
@FanKiLL

Answering your second question. Create a polymorphic Image model
and attach as many as you like to the Task via has_many. And not only to tasks - it's a polymorphic model.
for example

class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true

  mount_uploader :picture, ImageUploader #ваш аплоадер
end

class Task < ActiveRecord::Base
  has_many :images, as: :imageable, dependent: :destroy
end

migration for Image
class CreateImages < ActiveRecord::Migration
  def change
    create_table :images do |t|
      t.string :picture
      t.integer :imageable_id
      t.string :imageable_type
      t.timestamps
    end

    add_index :images, [:imageable_id, :imageable_type]
  end
end

Now you can attach as many pictures as you want to tasks, for example
@task = Task.new
@task.images <<  Image.new
@task.images <<  Image.new

Etc.
For the first question, see the answer here - stackoverflow.com/questions/23899860/actiondispatc...

B
buurz, 2014-09-18
@buurz

Thank you for your reply. But apparently I didn't express myself correctly.
I have only one question. How to attach multiple images to a . So far, I've only been able to attach one image. I tried to change the directive, but it did not help :

app.directive 'uploadImage', ->
    return{
      restrict: 'A'
      link:(scope,elem)->
        elem.on 'change', ->
          i = 0

          while i < elem.length

            x = 0

            while x < elem[i].files.length
              reader = new FileReader()
              reader.onload =(e)->
                scope.iFile = btoa(e.target.result)
                scope.$apply()
              file = elem[i].files[x]
              scope.iFile = ""
              scope.iFilesize = file.size
              scope.iFiletype = file.type
              scope.iFilename = file.name
              scope.$apply()
              reader.readAsBinaryString file
              x++
            i++
          return
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question