Best Practices when using Ember Data

I’m look for more complete example or tutorial on “Best Practices When Using Ember Data”. The Ember guides and meetup videos are helpful but I have yet to see a complete example with the correct usage of Routes, Controllers, Views, Models and Transactions.

The basic flow of the example application - list of contacts with an contact index and edit controller/view. The edit’s contact form view has a ‘cancel’ button which should rollback the transaction.

If anyone can improve or provide me with best practices I will update my GitHub ember-data-contacts example application, https://github.com/ttdonovan/ember-data-contacts/blob/master/js/app.js.

Thanks.

Hi, did you build your example from @dgeb “Ember data example” ? I think it’s actually exactly what you’re looking for.

You may have already seen this but the Ember.js screencast by PeepCode goes through the development of an entire Ember app. I found it very instructive, though I haven’t seen the meetup videos so I don’t have much to compare it to.

@sly7_7 yes I did see @dged Ember data example, but I am uncertain about the ‘isEditing’ property on the ContactControler. Just not sure if it is right, shouldn’t the transactions be in the routes :enter and :exit? And what about the ContactEditRoute (contact/:contact_id/edit) as is in the example the ContactRoute does both display and edit. If a users uses the browser address bar to navigate between states it appears might have an issue managing the correct application state between ContactRoute and ContactEditRoute without additional coding. Maybe I just need to review the example in greater detail again. Thanks for replying.

@dogonthehorizon Yes I have seen the Ember.js screencast and I believe it’s a great resource for anyone to jump into Ember development. However, I believe it doesn’t go into enough detail about ember-data, maybe that is another screencast yet to come. Thanks for the reply.

Agreed, although this may be because ember-data is in a state of flux right now. I’ll be interested in seeing how your ember-data experiments go; in fact it’s possible that I’ll have some time this weekend to fork it and explore things a little myself. I’ll send you a pull if I find anything interesting :smiley_cat:

I think @dgeb could explain the implementation details. Concerning the isEditing property and the transactions, I don’t know what’s the best practice, I think both are valid. Concerning the route management, you maybe right, there is something appearing to be weird here. I think this has been done like that in order to share the ‘edit’ feature between new and edit.

@ttdonovan @sly7_7 My plan all along has been to blog about this example and explain it in detail. I can see how some of the design decisions might seem a bit confusing or unconventional.

For instance, it might seem a bit more conventional to provide unique routes for every action, such as showing vs editing a contact. However, I wanted to illustrate in-place editing for the ContactRoute, which shows the possibility of managing some state in the controller (via the isEditing flag). I don’t think that routes should manage every bit of application state. For instance, I think that transactions belong in the controller layer, and not in routes. In my example, when creating or editing contacts, you can also edit associated phone numbers. These need to be managed by the controller and added to the same transaction as the contacts themselves.

I think routes should be used to set up controllers with a context, and should convey activation / deactivation to controllers. I think it’s inappropriate to treat routes as catch-all event handlers, and that events should be handled at the layer that is most appropriate: be it view, controller, or route (or parent route).

Anyway, my example is far from perfect and does need further cleanup. There are areas of repetition that could be tightened up and the tests need filling out. I’ll try to get to this soon so I can finally get back to blogging. Criticism and PRs welcome :slight_smile:

@dgeb thank you for the detailed reply. After reading I now have a better understanding around the design decisions you chose. My professional work is Ruby/Rails, developing an Ember application is a much different experience. I’m trying integrate Ember within my day-to-day work in business back-end applications (not ready to tackle a customer facing application yet). It appears with Ember that there are many ways to implement desired functionality. I’m just trying to understand the best practices and knowing when to use which design, example being the single ContactController/Route vs ContactEditControler/Route.

@ttdonovan In general, I don’t think that edit forms should be routable, although it really is an app-specific decision. When deciding whether an action should be routable, I find it helpful to think about whether it belongs in the browser history (i.e. can it be backed out of with the back button) and whether it makes sense to share links to that particular action. These are the same decisions you need to make in Rails apps when deciding whether to allow for “in place” editing.

If you have the transactions in the controller layer and not the route, how do you handle users using the back/forward button or clicking some other link in the app?

@lookingsideways The routes need to tell controllers about those changes. For instance, I might call controller.startEditing() from the route’s setupController(), and controller.stopEditing() from the route’s deactivate() (well, in the latter case, the controller needs to be looked up). The whole point is that the controller is relatively opaque to the route, and only needs to know what is being edited and when to start/stop editing. I don’t think that routes should need to know how something’s edited, and therefore shouldn’t manage editing details like transactions.

This is indeed a big problem that we have ran into in our app. The problem being that there is no guaranteed place to ensure that you can rollback the transaction. In our app not every model editing is attached to a route so there is not the luxury of a deactivate to stopEditing and roll things back. In any decent sized app, not everything is going to be attached to a route, I don’t think that is practical or advisable. We took the route of creating a form object for new records which is just really a bit of a glorified hash. The controller is bound to this form object and that way we only call createRecord when the user has clicked save or whatever and we create the record from the form hash. This gets round the problem of cleaning up unused transactions.

I can’t help thinking that the cleaning up of unused transactions is framework code and not something the developer wants to concern themselves with because there is not always the luxury of a deactivate to rollback and you end up putting in workarounds for a very, very, very common scenario that is troubling.

It would be great if we could come to a common ground because I don’t like using deactivate in the route, it feels out of place.