jqueryruby-on-railscontroller

Dropzone, can destroy from database but not from its container


I have a picture new page, where a user can upload boat pictures. So Boat model and Picture model associated and they are nested routes. So the thing is, I use Carrierwave and Dropzone. Writing to database works fine. I had struggled with the destroy action for nested routes as also I am not an expert on jquery. So Right now, when I click to remove button it actually destroys the picture from the database, but the picture remains inside of the Dropzone container.

Here;

enter image description here

This is the log output;

>Boat.last.pictures.all
  Boat Load (0.3ms)  SELECT  "boats".* FROM "boats"  ORDER BY "boats"."id" DESC LIMIT 1
  Picture Load (0.4ms)  SELECT "pictures".* FROM "pictures" WHERE "pictures"."boat_id" = ?  [["boat_id", 137]]
=> #<ActiveRecord::AssociationRelation [#<Picture id: 645, name: nil, boat_id: 137, created_at: "2015-04-24 22:13:29", updated_at: "2015-04-24 22:13:29", image: "imgres-3.jpg">]>

Then I press Remove file, it just moves a bit down instead of vanishing from there;

enter image description here

But it is removed from the database, the log again;

> Boat.last.pictures.all
  Boat Load (0.4ms)  SELECT  "boats".* FROM "boats"  ORDER BY "boats"."id" DESC LIMIT 1
  Picture Load (0.3ms)  SELECT "pictures".* FROM "pictures" WHERE "pictures"."boat_id" = ?  [["boat_id", 137]]
=> #<ActiveRecord::AssociationRelation []>

So I know the problem is with the Jquery but maybe someone is looking for how to use the #destroy action to use with dropzone. That is why I wanted to explain a bit.

my picture new.html.erb

<div class="container">

<%= form_for [@boat, @picture], html: { multipart: true, class: "dropzone", id: "picture-dropzone"} do |f| %>


      <p>

      <div class="fallback">
      <%= f.file_field :image %> 

      </div>    

      </p>

<% end %>

<p><%= link_to "Back to My Profile",  current_user %></p>


<div class="index">
  <%= render "index" %>
</div>


<script type="text/javascript">
$(document).ready(function(){
    // disable auto discover
    Dropzone.autoDiscover = false;

    // grap our upload form by its id
    $("#picture-dropzone").dropzone({
        // restrict image size to a maximum 5MB
        maxFilesize: 5,
        // changed the passed param to one accepted by
        // our rails app
        paramName: "picture[image]",
        // show remove links on each image upload
        addRemoveLinks: true,
        // if the upload was successful
        success: function(file, response){
            // find the remove button link of the uploaded file and give it an id
            // based of the fileID response from the server
            $(file.previewTemplate).find('.dz-remove').attr('id', response.fileID);
            $(file.previewTemplate).find('.dz-remove').attr('boat_id', response.boatID);
            // add the dz-success class (the green tick sign)
            $(file.previewElement).addClass("dz-success");
        },
        //when the remove button is clicked
        removedfile: function(file){

            // grap the id of the uploaded file we set earlier
            var id = $(file.previewTemplate).find('.dz-remove').attr('id'); 
            var boat_id = $(file.previewTemplate).find('.dz-remove').attr('boat_id'); 
            // make a DELETE ajax request to delete the file
            $.ajax({
                type: 'DELETE',
                url: '/boats/' + boat_id + '/pictures/' + id,
                success: function(data){
                    console.log(data.message);
                }
            });
        }
    }); 
});



</script>

And the pictures controller;

#create action

def create

    @picture = @boat.pictures.new(picture_params)

    if @picture.save
    render json: { message: "success", fileID: @picture.id, boatID: @boat.id }, :status => 200

    else
      render json: { error: @picture.errors.full_messages.join(',')}, :status => 400

    end

  end

#destroy action;

def destroy

    @picture = @boat.pictures.find(params[:id])
    if @picture.destroy
     render json: { message: "File deleted from server" }
    else
      render json: { message: @upload.errors.full_messages.join(',') }
    end
  end

So as I stated, the problem is with jquery, the removed file stays there.. Thank you


Solution

  • Add this two row into removedfile eventhandler function:

    var _ref;
    return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
    

    After this, your handler function should looks like this:

    removedfile: function(file){
    
        // grap the id of the uploaded file we set earlier
        var id = $(file.previewTemplate).find('.dz-remove').attr('id'); 
        var boat_id = $(file.previewTemplate).find('.dz-remove').attr('boat_id'); 
        // make a DELETE ajax request to delete the file
        $.ajax({
            type: 'DELETE',
            url: '/boats/' + boat_id + '/pictures/' + id,
            success: function(data){
                console.log(data.message);
            }
        });
    
        var _ref;
        return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
    }
    

    This should do the trick.