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;
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;
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
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.