Search code examples
ruby-on-railsruby-on-rails-4ember.jsember-rails

ember-rails not loading hasMany Association


Gems Used:

Using ember-source (1.5.1.1)
Using ember-data-source (1.0.0.beta.7)
Using ember-rails (0.15.0)
Using handlebars-source (1.3.0)
Using active_model_serializers (0.8.1)

This is the ember app code:

window.App = Ember.Application.create
  LOG_TRANSITIONS: true
  rootElement: '#app-ember-root'

App.store = DS.Store.extend({});

App.ApplicationAdapter = DS.ActiveModelAdapter.extend({});

App.Router.map ()->
  @resource 'quotes',
    path: '/'

App.QuotesRoute = Ember.Route.extend
  model: ()->
    this.store.find 'quote'

App.CompaniesQuote = DS.Model.extend
  quote: DS.belongsTo 'quote'

App.Quote = DS.Model.extend
  message: DS.attr 'string'
  createdAt: DS.attr 'date'
  companiesQuotes: DS.hasMany('companiesQuote')
  companiesQuotesCount: (->
    this.get('companiesQuotes.length')
  ).property('companiesQuotes')

Serializers:

class QuoteSerializer < ActiveModel::Serializer
  attributes :id, :message, :created_at

  has_many :companies_quotes
end

class CompaniesQuoteSerializer < ActiveModel::Serializer
  attributes :id, :company_id
end

Template quotes.handlebars:

<div class="quotes-list">
  <div class="quote-container">
    {{#each}}  
      {{ companiesQuotesCount }} companies quote for this quote {{ id }}
    {{/each }}
  </div>
</div>

/quotes JSON response:

{
   "quotes":[
      {
         "id":10,
         "message":"Quote 10!",
         "created_at":"2014-06-04T17:00:01.000Z",
         "companies_quotes":[
            {
               "id":27,
               "company_id":1
            },
            {
               "id":28,
               "company_id":2
            },
            {
               "id":26,
               "company_id":3
            }
         ]
      },
      {
         "id":11,
         "message":"Quote 11!",
         "created_at":"2014-06-11T14:45:02.000Z",
         "companies_quotes":[
            {
               "id":30,
               "company_id":1
            },
            {
               "id":31,
               "company_id":2
            },
            {
               "id":29,
               "company_id":3
            }
         ]
      }
   ]
}

With this env/code, the property companiesQuotesCount is always 0. What am I missing?

Solved

Using the @kingpin2k's response, I changed the JSON structure modifying QuoteSerializer:

class QuoteSerializer < ActiveModel::Serializer
  embed :ids, include: true
  attributes :id, :message, :created_at
  has_many :companies_quotes
end

Solution

  • Ember Data doesn't do embedded records by default.

    You'll either need to fix the json using a client side serializer, or fix it server side.

    It should be in this format:

    {
       "quotes":[
          {
             "id":10,
             "message":"Quote 10!",
             "created_at":"2014-06-04T17:00:01.000Z",
             "companies_quotes":[27, 28, 29]
          },
          {
             "id":11,
             "message":"Quote 11!",
             "created_at":"2014-06-11T14:45:02.000Z",
             "companies_quotes":[30, 31, 32]
             ]
          }
       ],
       companies_quotes:[
          {
             "id":27,
             "company_id":1
          },
          {
            "id":28,
            "company_id":2
          },
          {
            "id":26,
            "company_id":3
          },
          ....
       ]
    }
    

    Here's an example for using extractArray http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_extractArray

    Additionally your computed property is just watching the reference, which won't change as the length changes.

    companiesQuotesCount: (->
      this.get('companiesQuotes.length')
     ).property('companiesQuotes.length')