EmberJS - how to restructure embedded models?

63 Views Asked by At

Note: Using Ember Rails 0.18.2 and ember-source 1.12.1

I have inherited an Ember app that has a strange function. I am new to Ember so maybe this is normal, but I find it odd.

There are 3 models:

  1. Parents
  2. Games
  3. Comments

When a Parent views a game the url looks like this:

/<parent slug>/games/<game_id>

(the slug is just a unique id for the parent).

At this url there is a template that has this code:

  {{#unless commentsOpen}}
  {{#link-to 'comments' class="Button easyButton"}}Chat with parents in your pod{{/link-to}}
  {{/unless}}

  {{outlet}}

Clicking the above button then changes the url to this:

/<parent slug>/games/<game_id>/comments

Then all the comments appear for that game.

I need to remove that button from the view and have Comments display automatically for each Game.

The API is Rails, and I can already change the API endpoint to return all the Comments at the same time a Game is requested (as an embedded array of objects).

But what do I replace {{outlet}} with? Because my understanding is that {{outlet}} is delegating to the Comments template due to this route:

App.CommentsRoute = Ember.Route.extend
  model: ->
    return this.store.find('comment', {
      game:   @modelFor('game').get('id')
      parent: @modelFor('parent').get('slug')
    }).then( (models) -> models.toArray() )

I believe I need to remove that route and make the Comments an embedded object inside the Game model. Do I then just replace outlet with something like:

{{#each comment in Game}}

<div class="commentItem">
  <div class="commentItem-author">{{comment.parent_name}}</div>
  <div class="commentItem-body">{{comment.body}}</div>
</div>

{{each}}

EDIT

This is the router:

App.Router.map(function() {
  this.route('index', {
    path: '/'
  });
  return this.resource('parent', {
    path: '/:parent_id'
  }, function() {
    this.resource('games', {
      path: '/games'
    });
    return this.resource('game', {
      path: '/game/:game_id'
    }, function() {
      return this.resource('comments', {
        path: '/comments'
      });
    });
  });
});
2

There are 2 best solutions below

0
On BEST ANSWER

Embedding the Comments inside Game is the answer. Then the view is like this:

{{#each comment in model.comments}}

<div class="commentItem">
    <div class="commentItem-author">{{comment.parent_name}}</div>
    <div class="commentItem-body">{{comment.body}}</div>
</div>

{{/each}}
3
On

Let's say you have your current app, and that presumably somewhere you have a list of games likes so:

{{#each games as |game|}}
  <li>
    {{#link-to 'game' game}}
       {{game.title}}
    {{/link-to}}
  </li>
{{/each}}

you should be able to route directly to the game with comments, by changing your link-to, like so:

{{#link-to 'games.game.comments' game}}

Here is a twiddle with a detailed solution