backbone.js + restful con epiphany + fuelUX datagrid + Bootstrap: Parte 3 model de backbone.js

Ahhhhhhh... esa fué mi expreción cuando entendí por que no me funcionaba.

Esta es una entrada corta, muy corta, por que veremos la parte que relaciona el CRUD del RESTful entre backbone.js y epiphany.

La idea de utilizar backbone era que se estaba mapeada a RESTful, entoces, teniamos el etendido que, operando con modelos:



BackboneEpiphanyCRUD
model.save() (sin id) getRoute()->post(); CREATE
model.fetch() getRoute()->get(); READ
model.save() getRoute()->put(); UPDATE
model.destroy() getRoute()->delete(); DELETE

Ahora, si nos fijamos, la parte Create y Update, solo hay una pequeña diferencia, si el modelo tiene o no tiene id. 

En la primera parte, se define un modelo "sencillo" que será utilizado en una colección:
var User = Backbone.Model.extend({
  idAttribute: "tabletaEntryid"
});
var Users = Backbone.Collection.extend({
  model:User,
  url:function (){
    return "/sync/users/fromid/"+this.maximoId+"/offset/"+this.pageSize;
  },
  pageIndex:0,
  pageSize:0,
  maximoId:0,

});


 Y la propiedad url, que uno supone es la "base" para el resftul, tanto en la colección como en la parte del modelo, sin embargo, la documentación de Backbone.js dice al respecto sobre el modelo:
urlmodel.url()
Returns the relative URL where the model's resource would be located on the server. If your models are located somewhere else, override this method with the correct logic. Generates URLs of the form: "[collection.url]/[id]" by default, but you may override by specifying an explicit urlRoot if the model's collection shouldn't be taken into account. You can also pass in the model's url as an option when instantiating it.
Delegates to Collection#url to generate the URL, so make sure that you have it defined, or a urlRoot property, if all models of this class share a common root URL. A model with an id of 101, stored in a Backbone.Collection with a url of "/documents/7/notes", would have this URL: "/documents/7/notes/101"
urlRootmodel.urlRoot or model.urlRoot()
Specify a urlRoot if you're using a model outside of a collection, to enable  the defaulturl function to generate URLs based on the model id. "[urlRoot]/id"
Normally, you won't need to define this. Note that urlRoot may also be a function.
Lo cual, me hizo suponer, por no leer y entender bien,  que la definición de un modelo era:
var Cliente=Backbone.Model.extend({
    url: '/sync/infocliente',
})

Con eso, defines el URL específico para la colección y los puts, delete van directo al url SIN formar la parte resftul de url/:id, la forma correcta de definirlo es:
var Cliente=Backbone.Model.extend({
    urlRoot: '/sync/infocliente',
})

La diferencia es, y la documentación lo marca, pero solo lo entendí en base a "hack and slash" que urlRoot se usa cuando definimos un modelo FUERA de una colección, mientras que url es para especificar el url único del modelo o se delega su construcción a la colección.

Ahora, como, dice la nota en la tabla, para que el modelo haga post para crear un elemento del modelo o un post es si tiene definida la propiedad id:
var c = new Cliente({id: 1, fecha='hoy'});

Define un modelo completo.
c.set({tipo:'Mal cliente'});
c.save()
genera un put a /sync/infocliente/1 se ejecuta
en cambio
var c= new Cliente({tipo:'Mal cliente'});
c.save(); 
genera un post a /sync/infocliente


Esto se mapea con el epiphayny de la siguiente forma:
getRoute()->get('/sync/infocliente/(\d+)', array("sync", "infoclient"));
getRoute()->put('/sync/infocliente/(\d+)', array("sync", "updatecliente"));
getRoute()->delete('/sync/infocliente/(\d+)', array("sync", "deletecliente"));
Todo esta sencillo, excepto que en el put, php no "pela" el request ni lo transforma en nada de variable, por lo tanto hay que leerlo y backbone manda un objeto json que hay que interpretar:
  /**
    Actualiza un dato del cliente vía put
  */
  function updateCliente($id=null)
  {
    if(is_null($id))
    return;
    $id=intval($id);
    if($id<1)
    return;
    $putdata = file_get_contents("php://input");
    $vars=json_decode($putdata);
    if($id!=$vars->id)
    return;
}
La lectura de la información del request put la leo y transformo en objeto json de la siguiente forma:
    $putdata = file_get_contents("php://input");
    $vars=json_decode($putdata);

Y luego de lo que me dí cuenta, es que model.save() manda todos los atributos del elemento, por lo tanto puedo validar que el id del modelo sea igual al id del request como se ven en:
    if($id!=$vars->id)
    return;

Bueno, con eso termino mi experimentación por el momento... 
Previous
Next Post »

1 comentarios:

Write comentarios
Arab Academy
AUTHOR
10 de septiembre de 2016, 4:04 delete

Thank you for sharing knowledge and thanks for fantastic efforts
fire fighting academy
Firefighter I *

Reply
avatar