2012-09-22 6 views
14

¿Cómo se manejan los recursos singulares en Ember-Data? Decir que tengo las siguientes rutas REST:Cómo manejar recursos singulares con RESTAdapter

GET /cart 
POST /cart 
UPDATE /cart 
DELETE /cart 

brasa-datos find() espera para devolver una matriz, además de que intenta automáticamente pluralizar cualquier URL que pase a mi modelo. ¿Cuál es la mejor manera de manejar esta situación?

Respuesta

7

Hay una serie de cosas que puede hacer aquí.

El RESTAdapter llama a pluralize, que agrega una "s" al final del nombre o busca el nombre en el hash de plurales si existe. Suponiendo que su DS.Model es App.Cart.

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L209

DS.RESTAdapter.create({ 
    plurals: { 
    cart: 'cart' 
    } 
}); 

Si su esquema de URL es muy diferente y requiere un poco de lógica aún más, en realidad se puede anular la función buildURL.

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L288

DS.RestAdapter.create({ 
    buildURL: function() { 
    return "/always_this" 
    }) 
}); 
+0

Reemplazando la función buildURL se aplicará a todos los modelos, ¿verdad? ¿Qué hay de mis modelos no singulares? Además, incluso si cambio los plurales, 'find()' (sin argumentos) espera una matriz de objetos, por lo que no funcionará. Y si paso una identificación falsa para encontrar, entonces tengo que modificar las rutas de mi servidor para aceptar un argumento de id ('/ cart /: fake_id') solo para ignorarlo por completo. Parece demasiado hacky para algo tan común y simple. –

+0

Build URL puede hacer algo como esto: '' if (record.get ('singularResouce') {...} else {this._super.apply (this, arguments);} ''. The (...) puede sea ​​su propia función de creación de URL, y sus modelos singulares tendrán '' DS.Model.extend ({singularResouce: true}) ''. – Ryan

+0

Incluso puede hacer algo llamativo como llamar '' buildUrl'' de nuevo, pero pase indefinido como el id. – Ryan

3

Así, encontré this pull request en github. Es 8 meses de edad, por lo que no funcionará debido a la complejidad añadida desde entonces, pero he implementado la solución sugerida, así:

App.store = DS.Store.create({ 
    revision: 4, 
    adapter: DS.RESTAdapter.create({ 
    plurals: { 
     'cart': 'cart' 
    } 
    }) 
}); 

App.Cart.reopenClass({ 
    find: function() { 
    this._super("singleton"); 
    } 
}); 

En mi servidor (estoy usando rieles), tengo que añadir el siguiente a mis rutas:

get "cart/:ignored" => "carts#show" 

entonces tengo que añadir lo siguiente a CartSerializer (usando active_model_serializers joya):

attributes :id 
def id 
    "singleton" 
end 

Esto es necesario, ya que, al parecer, si el id en la respuesta json no coincide con el ID solicitado de find() (singleton en este caso), entonces ember no cargará los datos en el modelo.

Ahora bien, obviamente esta no es la solución ideal, pero hasta que los datos de ember no lo añadan, parece que es la forma menos dolorosa de hacerlo.

Por cierto, presenté an issue para agregar soporte.

+0

Intenté implementar esta solución y funciona en la carga inicial ... pero una vez que navego a otra pestaña y vuelvo a la pestaña de recursos singulares, el punto final de la API no se vuelve a llamar. ¿Algunas ideas? – flynfish

2

Así es como obtuve este funcionamiento en Ember 1.9. Primero leo this section de la guía. En la parte inferior, explica cómo anular un adaptador para un solo modelo.

función
App.CartAdapter = App.ApplicationAdapter.extend { 
    pathForType: -> 
    'cart' 
} 

El pathForType es donde ocurre la pluralización (al menos en el RESTAdapter el que estoy usando) por lo que ninguno de los otros funcionalidad del adaptador se ve afectado (como anfitrión, o espacio de nombres).

1

Solo para compartir una solución más completa que me funciona, amplíe el ApplicationRouter de su aplicación (que a su vez amplía DS.RESTAdapter).

App.CartAdapter = App.ApplicationAdapter.extend({ 
    pathForType: function(type) { 
     return 'cart'; 
    } 
}); 

A continuación, defina su recurso en App.Router.mapa:

this.resource('cart'); 

Finalmente, pase una cadena vacía como la identificación en su ruta. Esto es lo que permite que la URL se genere sin una identificación.

App.CartRoute = Ember.Route.extend({ 
    model : function(params) { 
     return this.store.find('cart', ''); 
    } 
}); 
Cuestiones relacionadas