简体   繁体   中英

Backbone.model.save(): POST(create) / PUT(update) logic doesn't match application logic - how to avoid PUT in certain situations?

I'm creating an Web-Application (Frontend and Backend, so both are under my control) using Backbone and Pyramid, being connected via a RESTful API.

During development I encountered a problem several times by now, where Backbone PUTs (=updates) a new model, while it actually should POST (=create) it.

Backbone decides whether to POST or UPDATE a model depending of the presence of an ID -field (if no ID present in the current model: -> POST/create | if so: PUT/update).

However I encountered several situations by now, where this behaviour doesn't match my application logic.

Let's say our main model (and its objects being persistently saved in a relational database in the backend) is called Foo , having fields like id , field_1 , field_2 .

Example #1 : Creating a template or preview of Foo : Before creating (= POST ing) an object of Foo , I can create and show a preview to the user and/or save it as a template. While doing so, the backend (in case of the preview: temporarily) adds the object to the database and returns the full model - including an ID in its HTTP response - back to Backbone. Template- and Preview-objects of Foo are (temporarily) saved into the same table, as final objects (column type indicates its type ( 0 = final/live, 1 = preview, 2 = template)). When now - after previewing / saving as template - trying to actually CREATE an object of Foo , the Backbone model already has the ID field set and actually PUT s and updates the template or not-anymore-existing preview, instead of POST ing and therewith creating a new Foo inside the database (as intended).

=> solution #1 : calling POST /json/preview does not return the ID field, so Backbone doesn't get confused.

=> solution #2 : overriding parse() of Foo in Backbone-model to kick out ID field from response

.=> kinda works

Example #2 : Having a Periodic model, which refers to a Foo -template. Intention of a Periodic is to offer the user the possibility of semi-automatically creating a new Foo object based on a Foo -template every X months.

Now there is a call GET /json/periodics, which returns all Periodic -objects with its nested Foo -objects ( Foo -templates), including their IDs, eg [{'interval': 12, template_id: 42, template: { 'id': 42, field_1: 'foo', field_2: 'bar', .. } , { .. } , .. ] .

On the frontend the user now can periodically confirm (or skip) creating a new Foo -object, by issuing: periodics[X].template.save() which however again PUT s and therewith updates the Foo -model, instead of POST ing and creating a new one (as intended).

Here again (as in example 1), I could strip out the ID field of Foo - either in the backend or frontend.

However there are situations, where I need the id -field of templates, eg when actually editing them, so here I'd need two calls ( GET /json/templates_WITHOUT_FOO-IDs and GET /json/templates_WITH_FOO-IDs ). which also sounds far from right.

Question is : What's the right (and consistent) way of avoiding Backbone falsely assuming a model should be PUT instead of POST ed in certain situations / views?

Backbone's save and fetch methods just make calls to the Backbone.sync method, which in turn is just a wrapper for an ajax call. you can pass in ajax parameters using the save function without having to actually extend it. basically ends up being something like this:

model.save({attributes you want to save}, {type:'POST', url: 'apiurl/model/:id/played'});

You would have to do this every time though so it is probably better practice to extend Backbone.sync for your model.

The Backbone website has a bit of information about what I'm talking about as far as the Backbone sync and save taking ajax options. There are also a few examples I've seen on extending sync but I can't seem to track them down at the moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM