How to use multiple ember data models in one view

Given the data of the JSON data model on a RESTful server

/ users

{"users":[ {"id":"1","first_name":"John","last_name":"Doe"}, {"id":"2","first_name":"Donald","last_name":"Duck"} ]} 

/ users / 1

 {"user": {"id":"1","first_name":"John","last_name":"Doe","account":"1"} } 

/ accounts

 {"accounts":[ {"id":"1","owned_by":"1"},{"id":"2","owned_by":"2"} ]} 

/ accounts / 1

 {"account": {"id":"1","owned_by":"1","transactions":[1,17]} } 

and these Ember data models

 App.Store = DS.Store.extend({ revision: 11, adapter: DS.RESTAdapter.create({ url: 'http://api.mydomain.ca' }) }); App.User = DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), account: DS.belongsTo('App.Account') }); App.Account = DS.Model.extend({ ownedBy: DS.belongsTo('App.User'), transactions: DS.hasMany('App.Transaction') }); 

What other ember code do I need to write to load data into the model, and then write a template that displays the username, account ID, and number of transactions in the account?

+6
source share
2 answers

I was able to solve this, so I will post my code if it helps someone else. The trick is to make sure that the JSON data is formatted exactly as Ember wants, and to create the correct routes.

From what I can tell, Ember expects parent objects to provide a list of child objects. This seems strange to me, so if someone knows a way to do this with children that reference their parents using a foreign key, please let me know.

I changed the account property to my / user /: user_id JSON object on account_id. I also included account_id in the user objects found in / users, and I changed the own_by property in the account to user_id.

My javascript file

 var App = Ember.Application.create(); // Router App.Router.map(function() { this.resource('users', function() { this.resource('user', {path:':user_id'}); }); // '/#/users/:user_id' this.resource('accounts', function() { this.resource('account', {path:':account_id'}); }); }); App.IndexRoute = Ember.Route.extend({ redirect: function() { this.transitionTo('users'); } }); App.UsersRoute = Ember.Route.extend({ model: function() { return App.User.find(); } }); App.AccountsRoute = Ember.Route.extend({ model: function() { return App.Account.find(); } }); // Controllers App.TransactionsController = Ember.ArrayController.extend(); // Adapter App.Adapter = DS.RESTAdapter.extend({ url: 'http://api.mydomain.ca' }); // Models App.Store = DS.Store.extend({ revision: 11, adapter: App.Adapter.create({}) }); App.User = DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), account: DS.belongsTo('App.Account') }); App.Account = DS.Model.extend({ user: DS.belongsTo('App.User'), transactions: DS.hasMany('App.Transaction'), balance: function() { return this.get('transactions').getEach('amount').reduce(function(accum, item) { return accum + item; }, 0); }.property(' transactions.@each.amount ') }); App.Transaction = DS.Model.extend({ account: DS.belongsTo('App.Account'), amount: DS.attr('number'), description: DS.attr('string'), timestamp: DS.attr('date') }); 

And pen patterns

 <script type="text/x-handlebars" data-template-name="application"> <div class="row"> <div class="twelve columns"> <h2>Accounts</h2> <p>{{outlet}}</p> </div> </div> </script> <script type="text/x-handlebars" data-template-name="users"> <div class="row"> <div class="three columns" id="users"> {{#each user in controller }} {{#linkTo "user" user class="panel twelve columns"}}{{user.firstName}} {{user.lastName}}{{/linkTo}} {{/each}} </div> <div class="nine columns" id="user"> {{ outlet }} </div> </div> </script> <script type="text/x-handlebars" data-template-name="user"> <h2>{{firstName}} {{lastName}}</h2> {{#if account}} {{render "account" account}} {{else}} Error: Account not set up! {{/if}} </script> <script type="text/x-handlebars" data-template-name="accounts"> <div class="row"> <div class="three columns" id="accounts"> {{#each account in controller }} {{#linkTo "account" account class="panel twelve columns"}}{{account.id}} {{account.user.firstName}} {{account.user.lastName}}{{/linkTo}} {{/each}} </div> <div class="nine columns" id="account"> {{ outlet }} </div> </div> </script> <script type="text/x-handlebars" data-template-name="account"> <p>Account Number: {{id}}, Balance: {{balance}}, {{transactions.length}} transactions</p> {{render "transactions" transactions}} </script> <script type="text/x-handlebars" data-template-name="transactions"> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>Amount</th> <th>Timestamp</th> <th>Description</th> </tr> </thead> <tbody> {{#each transaction in controller}} <tr> <td>{{transaction.id}}</td> <td>{{transaction.amount}}</td> <td>{{transaction.timestamp}}</td> <td>{{transaction.description}}</td> </tr> {{/each}} </tbody> </table> </script> 
+3
source

Create an index route that populates your IndexController using the model and create an appropriate template that iterates over your relationships.

Here is an example of a simple HasMany-Link between a post and comments:

 var App = Ember.Application.create(); App.Store = DS.Store.extend({ revision: 11, adapter: DS.RESTAdapter.create() }); App.Post = DS.Model.extend({ comments: DS.hasMany('App.Comment') }); App.Comment = DS.Model.extend({ post: DS.belongsTo('App.Post'), body: DS.attr('string'), }); App.IndexRoute = Ember.Route.extend({ setupController: function(controller) { controller.set('content', App.Post.find("1")); } }); 

The HTML should look like this:

 <!DOCTYPE html> <html> <head> ... </head> <body> <script type="text/x-handlebars" data-template-name="index"> {{#each comment in content.comments}} {{comment.body}} {{/each}} </script> </body> 

And last but not least: server response / posts / 1

 { "post": { "id": 1, "title": "Rails is omakase", "comments": [1, 2, 3] }, "comments": [{ "id": 1, "body": "But is it _lightweight_ omakase?" }, { "id": 2, "body": "I for one welcome our new omakase overlords" }, { "id": 3, "body": "Put me on the fast track to a delicious dinner" }] } 
0
source

All Articles