Ember data JSONAPI complex attribute data

2019-08-12 05:22发布

I have a data structure as follows coming back from the server for some filter functionality I'm writing. Where each filter-group has many filters.

data: [
    {
        type: "filter-group",
        id: "556d7f5fa1f9de08500ef4e8_1",
        attributes: {
            name: "Colour",
            created-date: "0001-01-01T00:00:00Z",
            active: true,
            filters: [
                {
                    id: "556d7f5fa1f9de08500ef4e8_1_1",
                    name: "Red",
                    created-date: "0001-01-01T00:00:00Z",
                    active: true
                },
                {
                    id: "556d7f5fa1f9de08500ef4e8_1_2",
                    name: "Blue",
                    created-date: "0001-01-01T00:00:00Z",
                    active: true
                },
                {
                    id: "556d7f5fa1f9de08500ef4e8_1_3",
                    name: "Green",
                    created-date: "0001-01-01T00:00:00Z",
                    active: true
                }
            ]
        }
    }
]

And I have models set up as such:

// models/filter-group.js
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  active: DS.attr('boolean'),
  client: DS.belongsTo('client', { embedded: 'always' }),
  filters: DS.hasMany('filter', { embedded: 'always' })
});

And:

// models/filter.js
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  active: DS.attr('boolean'),
  createdDate: DS.attr('date'),
  filterGroup: DS.belongsTo('filter-group', { embedded: 'always' })
});

I'm new to working with JSONAPI, so I'm not sure if my data setup is the right way of going about this. I'm trying to loop through the filter-groups and then inside each, loop through its available filters, using the following handlebars template:

{{#each filterGroups as |filterGroup|}}
    <h6>{{filterGroup.name}}</h6>

    {{#each filterGroup.filters as |filter|}}
        -- Filter output here --
    {{/each}}
{{/each}}

But each filterGroup.filters object is empty. What am I doing wrong here? Am I completely misunderstanding the way the JSONAPISerializer works on structures like this?

1条回答
We Are One
2楼-- · 2019-08-12 05:58

In JSON API, while you can embed data within an attribute, you can't/aren't supposed to embed full resource objects (i.e., objects with their own type, relationships, etc.). I'm guessing that's what's tripping up Ember Data.

Instead, JSON API asks that you put these embedded resources in the included collection (see below). This allows multiple resources in the primary data to reference the same included resource, without that resource needing to be included multiple times in the payload. So the server response should look like this:

{
  "data": [{
    "type": "filter-group",
    "id": "556d7f5fa1f9de08500ef4e8_1",
    "attributes": {
      "name": "Colour",
      "created-date": "0001-01-01T00:00:00Z",
      "active": true
    },
    "relationships": {
      "filters": {
        "data": [
          {"type": "filters", "id": "556d7f5fa1f9de08500ef4e8_1_1"},
          {"type": "filters", "id": "556d7f5fa1f9de08500ef4e8_1_2"},
          {"type": "filters", "id": "556d7f5fa1f9de08500ef4e8_1_3"}
        ]
      }
    }
  }],
  "included": [{
    "type": "filters",
    "id": "556d7f5fa1f9de08500ef4e8_1_1",
    "attributes": {
      "name": "Red",
      "created-date": "0001-01-01T00:00:00Z",
      "active": true
    }
  }, {
    "type": "filters",
    "id": "556d7f5fa1f9de08500ef4e8_1_2",
    "attributes": {
      "name": "Blue",
      "created-date": "0001-01-01T00:00:00Z",
      "active": true
    }
  }, {
    "type": "filters",
    "id": "556d7f5fa1f9de08500ef4e8_1_3",
    "attributes": {
      "name": "Green",
      "created-date": "0001-01-01T00:00:00Z",
      "active": true
    }
  }]
}

Then, you may have to use something other than the embedded flag in Ember Data to get it to pick up the included resources—I'm not sure. But this is definitely the way to do it from the JSON API side.

查看更多
登录 后发表回答