Search code examples
ember.jsember-dataember-router

Ember.js: display items inside an hasMany relationship


Given these models:

App.TransportDocument = DS.Model.extend
  number: DS.attr 'string'
  date: DS.attr 'string'
  printable_url: DS.attr 'string'
  transport_document_rows: DS.hasMany('App.TransportDocumentRow')

App.TransportDocumentRow = DS.Model.extend
  product_name: DS.attr 'string'
  quantity: DS.attr 'number'
  measure: DS.attr 'string'
  transport_document: DS.belongsTo('App.TransportDocument')

here are my routes:

App.TransportDocumentsRoute = Ember.Route.extend
  model: -> App.TransportDocument.find()

App.TransportDocumentRoute = Ember.Route.extend
  model: (params)-> App.TransportDocument.find(params.transport_document_id)

App.TransportDocumentRowRoute = Ember.Route.extend
  model: -> App.TransportDocumentRow.find()

I have an handlebars template:

{{#each transport_document in controller}}
  td_id: {{transport_document.id}}
  {{#each transport_document_row in transport_document.transport_document_rows}}
    row_id: {{id}}
  {{/each}}
{{/each}}

i expected my result to be:

td_id: 1 row_id: 1 row_id: 2 row_id: 3
td_id: 2 row_id: 3 row_id: 4 row_id: 5
td_id: 3 row_id: 8 row_id: 7 row_id: 6

but is is:

td_id: 1 row_id: row_id: row_id:
td_id: 2 row_id: row_id: row_id:
td_id: 3 row_id: row_id: row_id:

here's my server response to /transport_documents

{"transport_documents":
  [
    {"id":1,"number":"11","date":"17/04/2013","cause":"Conto lavorazione","transport_document_row_ids":[3,2,1],"transport_document_rows":    
      [
        {"transport_document_row":{"id":3,"transport_document_id":1,"product_name":"suola puzzle verde","quantity":"1","measure":"pz","}},
        {"transport_document_row":{"id":2,"transport_document_id":1,"product_name":"lacci rossi","quantity":"2","measure":"pz"}},
        {"transport_document_row":{"id":1,"transport_document_id":1,"product_name":"Rotolo di tela","quantity":"50","measure":"m"}}
      ]},
    {"id":2,"number":"2","date":"18/04/2013","cause":"Conto lavorazione","transport_document_row_ids":[6,5,4],"transport_document_rows":
      [
        {"transport_document_row":{"id":6,"transport_document_id":2,"product_name":"suola puzzle verde","quantity":"1","measure":"pz"}},
        {"transport_document_row":{"id":5,"transport_document_id":2,"product_name":"lacci rossi","quantity":"2","measure":"pz"}},
        {"transport_document_row":{"id":4,"transport_document_id":2,"product_name":"Rotolo di tela","quantity":"50","measure":"m",}}
      ]},
    {"id":3,"number":"3","date":"19/04/2013","cause":"Conto lavorazione","transport_document_row_ids":[9,8,7],"transport_document_rows":
      [
        {"transport_document_row":{"id":9,"transport_document_id":3,"product_name":"suola puzzle verde","quantity":"1","measure":"pz"}},
        {"transport_document_row":{"id":8,"transport_document_id":3,"product_name":"lacci rossi","quantity":"2","measure":"pz"}},
        {"transport_document_row":{"id":7,"transport_document_id":3,"product_name":"Rotolo di tela","quantity":"50","measure":"m"}}]}

i guess i'm doing something wrong in the routes (where do i define the query to find all the rows of THAT document?) but i'm not sure. Can't find anything like that in the guides

thank you


Solution

  • As per convention, the default code in Route#serialize will return an object containing the model id, however the property name is not id, but rather the combination of the model name and id, which in your case, should be transport_document_id.

    The object returned by the serialize method will be passed as argument to Route#model. This is also explained in the routing guide.

    Your route should be something similar to the following:

    App.TransportDocumentRoute = Ember.Route.extend
      model: (params)-> 
        App.TransportDocument.find(params.transport_document_id)
    

    or you can override the serialize of your route to provide a different parameter name. You can find an example of a different implementation for serialize here.


    As for querying, you can filter similarly to the following:

    App.TransportDocumentRowRoute = Ember.Route.extend
      model: (params) -> App.store.filter App.TransportDocumentRow, (row) ->
        # might have to implement Route#serialize to also provide the 
        # transport_document_id property in this route
        row.get 'transport_document_id' == params.transport_document_id
    

    However, this would only filter the records you have in store. If the row records are not already fetched, you'll also have to fire a GET to fetch them.

    btw, sorry if the syntax is not 100%. I don't really speak coffee :)