11

I've got a backbone model that I'm trying to destroy, but no params are being sent with the request, so the server is returning a 'Delete 404 not found' error.

I'll admit my structure is a bit strange as I'm creating/destroying the items based on if they are in a list already or not.

var list_item = new MyApp.Models.ListItem({item_id: this.model.id, group_id: this.model.group_id});

    if($(e.currentTarget).hasClass('add')){

            list_item.save(list_item, { 
                success: function(response){
                     this.model.attributes.addedtolist_id = response.id
                     console.log(this.model);
                },
                error: function(){
                     alert('could not save item');
                }
           });
    } else if($(e.currentTarget).hasClass('remove')) {
         list_item.id=this.model.addedtolist_id;
         list_item.attributes.id = this.model.addedtolist_id;
         console.log(list_item);
         list_item.destroy({
             success: function(){
                alert('delete');
             },
             error: function(){
               alert('could not uncheck');
            }
   });
}

the console output for list_item before destroy is

_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
 id: 2
 item_id: 66
 group_id: 64
__proto__: Object
cid: "c23"
id: 2
__proto__: q

but when I look at the headers sent with the delete request, I don't have any params being sent.

-----------------------update params being sent, 404 still being returned --------------

as per Yaroslav's recommendation, I've added a 'header' to the destroy method, but my rails controller is still returning a DELETE 404 not found error. I'm just trying to return the listitem to make sure i'm getting the right one before I destroy it.

My controller is

 def destroy
   listitem = Listitem.find(params[:id])
   return render :json => listitem
 end
pedalpete
  • 21,076
  • 45
  • 128
  • 239
  • @muistooshort I've updated the formatting and added the missing brace. hopefully that's better. – pedalpete Jun 15 '12 at 06:03
  • Where does it get its `id`? I don't see it in the `new ListItem`. And what does the URL look like for the DELETE request? – mu is too short Jun 15 '12 at 06:48
  • It doesn't have an id in the `new ListItem` because that is when the listitem is being created, so it doesn't have an id yet. That is why I create the id before the `destroy`. The url is `DELETE http://10.1.1.7:3000/list_items 404 (Not Found)`. I use the same url for index and create methods, which work no problem. – pedalpete Jun 15 '12 at 07:05
  • 1
    And who builds that URL? Do you have `url` or `urlRoot` in `ListItem`? – mu is too short Jun 15 '12 at 07:11
  • @muistooshort, the url is defined in my backbone ListItem model, and therefore it is the same url as used on both the `fetch` and `save` which work fine. – pedalpete Jun 15 '12 at 09:11
  • @muistooshort, looks like you were right, the problem was in the url. When I manually added the url as `list_item.url = 'list_items/'+list_item.id`, it worked. I thought the way it worked was to send the delete as a param. If you add your url bit as an answer I'll accept it. – pedalpete Jun 16 '12 at 02:46

3 Answers3

30

I'd guess that you're setting the url in the model to a string:

Backbone.Model.extend({
    url: '/list_items',
    //...
});

That will tell Backbone to use exactly /list_items as the URL for all actions. You should use a function:

url: function() { return '/list_items/' + encodeURIComponent(this.id) }

or use a string with urlRoot and let the default url function add the id:

urlRoot: '/list_items'
mu is too short
  • 426,620
  • 70
  • 833
  • 800
2

What params are you expecting to be sent? Destroy makes just a http delete request by the url without body or any additional headers by default. The params argument is pased to the jquery ajax function, so you can specify headers there:

model.destroy({
...
    headers : {
        your_header : 123
    }
})
Yaroslav
  • 4,543
  • 5
  • 26
  • 36
  • thanks @Yaroslav, I was expecting the id to be sent as a param. I've added your 'headers', which is now sending the id as a param, but I'm still getting the 'DELETE' not found. – pedalpete Jun 15 '12 at 07:58
  • I could not see these parameters server side (Rails). I can't find much documentation on the options parameter of backboe destroy. Can you add links? Thanks! – oma Jun 28 '12 at 05:57
  • Unfortunately that isn't described in the documentation, found out in the source code. – Yaroslav Jul 02 '12 at 10:31
  • 2
    It's unfortunate that DELETE doesn't automatically send the model ID to the server along with the request. Adding it as a header feels hacky. – Shane Reustle Mar 16 '14 at 04:20
0
list_item.destroy( **l** {
  success: function(){
  alert('delete');
}, ... );

Is that extra number one the problem?

jakee
  • 18,486
  • 3
  • 37
  • 42
  • oopps, sorry @jakee, when it wasn't working I tried `list_item.destroy(list_item,{success...`, and left the l in there by accident. This is not the issue, it was an attempt at a fix. – pedalpete Jun 15 '12 at 05:09