0
votes

My ember router has this type of parent/child resource set up.

 this.resource("cities", function(){
         this.resource("city", { path: ':city_id'});

    });

In the backend (which is Rails), there is a has_many relationship between City.rb and Restaurant.rb, and in the Active Model Serializer (AMS) for the City, I also declare the has_many relationship with Restaurants. In the AMS, when declaring relationships, it gives you the option to do something like this

embed :ids, include: true

so that only the 'ids' for the child model (in my case, the restaurant) is included. I did not do that. Therefore, I get all the Restaurant attributes for each city when I do a findAll ajax request on the City.rb model. That means in the city template, I can display the name of each restaurant etc, because all of the restaurant data is at hand

 <script type="text/x-handlebars" id="city">

      {{ model.name }}//city name

      {{#each item in model.restaurants}}
      <li> 
      {{#link-to 'restaurant' item}}{{ item.name }}{{/link-to}}
     </li>
    {{/each}}

</script>

However, I have read that it's a best practice in Ember to in fact only embed ids for children models (in my case the restaurant) embed :ids, include: true, which means that the restaurant name would not be available in the above template.

My question is this, if I do embed :ids, include: true, when I'm displaying the template for each city, what use is it to only have the id present? It means that I couldn't display the list of restaurants for each city, and if I wanted to show them, I'd have to query individually for each city.

If that's correct, what's the use case for using embed :ids, include: true in Active Model Serializer with Ember. Is there a way I could have used it in this context to make the code more efficient?

Code

My city findAll method

App.City.reopenClass({

  findAll: function() {

     return $.getJSON("cities").then(
      function(response) {    
        console.log(response);     
        var links = Em.A();
        response.cities.map(function (attrs) {
          links.pushObject(App.City.create(attrs));
        });
        console.log(links);
        return links;
      }
    );
   },

   });

The cities template

<script type="text/x-handlebars" id="cities">

  <div class='span4'>
      {{#each item in model}}
      <li> {{#link-to 'city' item}}
      {{ item.name }} 
      {{/link-to }}</li>
    {{/each}}

         </ul>
     </div>

  <div class="span4 offset4">
   {{ outlet}}
   </div>

</script>

The city template that also shows the restaurants

<script type="text/x-handlebars" id="city">

      {{ model.name }} //city name

      {{#each item in model.restaurants}}
      <li> 
      {{#link-to 'restaurant' item}}{{ item.name }}{{/link-to}}
       </li>
      {{/each}}
</script>
2

2 Answers

0
votes

I believe embed: ids is generally used when you're utilizing Ember Data. After setting up model relationships in ED it would be able to look at the array of id's you provided with a relationship and side load them for the template where that data is needed.

Check out Embers Model (ED) docs for more info.

1
votes

Reading the doc of AMS here about embedded associations, it looks like using embed: ids, include: true side-loads the data alongside the objects beings loaded.

This means that, in your case, you will receive something like :

cities: [
    {id: 1, name: 'Paris', restaurant_ids: [1, 3]},
    {id: 2, name: 'Houston', restaurant_ids: [2]}
],
restaurants: [
    {id: 1, name: 'Septime'},
    {id: 2, name: 'Unknown restaurant'},
    {id: 3, name: 'Le Reminet'}
]

So you should be able to get the restaurants data without any further request, the only difference with the way you're describing at first, is that restaurants data won't be directly embedded in the cities data.

From AMS doc,

This makes it easier to process the entire package of data without having to recursively scan the tree looking for embedded information.

One use case of this configuration is the use of ActiveModelAdapter for Ember Data which requires embed: ids, include: true to work properly.