TrevTheDev
TrevTheDev

Reputation: 2737

How to display HasMany relationship in Ember

What is required to make this simple jsfiddle display a list of categories with products e.g.

View code:

<script type="text/x-handlebars" data-template-name="categories">
    {{#each}}
        <div>Category: {{name}}</div>
            {{#each product in this.products}}
                <div>Product: {{product.name}}</div>            
            {{/each}}
    {{/each}}
</script>

Model code:

App.Category = DS.Model.extend({
    name: DS.attr('string'),
    products: DS.hasMany('product')
});

App.Product = DS.Model.extend({
    name: DS.attr('string')
});

Route:

App.CategoriesRoute = Ember.Route.extend({
    model: function () {
        return this.store.find('category');
    }
});

Upvotes: 2

Views: 1857

Answers (3)

nothing-special-here
nothing-special-here

Reputation: 12568

Simple "How To" with Ruby on Rails 4:

-app/serializers/list_serializer.rb

class ListSerializer < ActiveModel::Serializer
  embed :ids, include: true

  attributes :id, :name
  has_many :tasks
end

-app/serializers/task_serializer.rb

class TaskSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :list_id
end

-app/javascripts/models/task.js

EmTasks.Task = DS.Model.extend({
  name: DS.attr('string'),
  description: DS.attr("string"),
  list: DS.belongsTo('list')
});

-app/javascripts/models/list.js

EmTasks.List = DS.Model.extend({
  name: DS.attr('string'),
  tasks: DS.hasMany('task')
});

Sample List controller:

class ListsController < ApplicationController
  respond_to :json

  def index
    respond_with List.all
  end
# ...

Then you will get JSON response for standard REST JSON API (/lists.json):

{
  lists: [
    {
      id: 15,
      name: "icebox",
      task_ids: [
        1
      ]
    }
  ],
  tasks: [
    {
      id: 1,
      name: "whatever",
      description: "",
      list_id: 15
    }
  ]
}

And you can print it in handlebars template:

  {{#each task in this.tasks}}
    {{task.name}}
  {{/each }}

Upvotes: -1

Daniel Berkompas
Daniel Berkompas

Reputation: 349

Here's a fully functional jsfiddle that demonstrates how to do this.

One of the other answers pointed out that you needed to add { async: true } to the hasMany relationship, and remove Ids from products.

This is true, however, it doesn't fix all your rendering issues. You also need to change your default route to:

App.Router.map(function () {
    this.route('categories', { path: "/" });
});

Then, create a CategoriesController extending Ember.ArrayController, with itemController set to 'category'. (See the Ember docs for more details) You can then create a CategoryController extending Ember.ObjectController.

Finally, update your #each statement to look like this:

{{#each category in controller}}

Again, here's the JSfiddle demonstrating how this works.

Upvotes: 1

Kingpin2k
Kingpin2k

Reputation: 47367

You need to make the relationship async and fix the json (remove the id)

async because the records aren't included with the Category

no appended id because that's not the format Ember Data expects https://github.com/emberjs/data/blob/master/TRANSITION.md

App.Category = DS.Model.extend({
    name: DS.attr('string'),
    products: DS.hasMany('product', {async: true})
});

App.Category.FIXTURES = [
    {    id: 1,    name: 'Shirts',   products: [1]},
    {    id: 2,    name: 'Pants',    products: [1,2]},
    {    id: 3,    name: 'Socks',    products: [3]},
    {    id: 4,    name: 'Shoes',    products: [3,4]}
];

http://jsfiddle.net/2Mguy/

Upvotes: 1

Related Questions