I’m running into a common pattern over and over again with Ember Data + Rails API + ActiveModel Serializers and am wondering what others are doing, if there’s a best practice, and feedback on my current approach.
Let’s say I have a Product model. When the user is at /#/products, the user should see a list of products with only the basic information: name, picture, and price. When the user goes to a product page, such as /#/products/1, he should see all the extended information about the product: reviews, variations, similar items, etc. Likewise, it seems to make sense to structure the API similarly: /products returns the basic information about many products, and /products/1 returns the extended information about a single product.
On the Rails side, I have two different Product serializers: one for the basic version and one for the detailed version, and the controller determines which serializer to use. Ember Data seems pretty happy with this approach, with one exception: when the user visits the /#/products page and then visits /#/products/1, the basic model is already loaded, so it will not necessarily know to reload the model to get the extended information. My solution for that is to define a DS.attr called “_received” that the detailed serializer will return as true. When the ProductIndexRoute retrieves the model, it calls reload() if _received is false.
The approach works fairly well, but it seems like a non-standard approach to a common problem. Is there a more standard approach? Anyone solving the problem differently?
I haven’t had to deal with this, but I my instinct would be to change the /#/products/:id route model hook to load the model with query parameters:
model: function() {
var id = this.modelFor('product').get('id');
return this.store.findQuery('product', { id: id, full: true });
}
I don’t know if this syntax is totally correct, but something similar I believe will force a reload of the model and your API can provide all the properties.
Thanks so much for the feedback, gentlemen. Really appreciate your time and knowledge.
@buuda, it seems like our approaches are very similar. The full=true query parameter does the same job as my _received property. I believe that findQuery() will return an array, so you’d have to select the first object in the array as well.
@Spencer_Price, you have a pretty different approach… very interesting. I like how it works out of the box using all of the basic conventions. The split of the models feels a little artificial, but it can definitely be a good price to pay for keeping everything conventional.