Ember Data, tree-like data, and parent links


#1

Hey all!

I have a model named Module. It looks like this:

import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr(),
    modules: DS.hasMany('modules', { inverse: null}),
});

Modules form a tree: there’s a “crate” model at the root, and it can contain zero or more modules, and then each module can contain zero or more child modules. It’s always a tree, not a general graph.

This is working great. My modules can see their children, everything works.

However, I want a link to the parent module from the child.

I have JSON that looks like this. As you can see, there’s also a “crate” module that has modules, this is the root of the tree.

{
    "data": {
      "type": "crate",
      "id": "example",
      "relationships": {
        "modules": {
          "data": [
            {
              "type": "module",
              "id": "example::nested1"
            }
          ]
        }
      }
    },
    "included": [
      {
        "type": "module",
        "id": "example::nested1",
        "attributes": {
          "name": "nested1",
          "docs": " nested 1\n"
        },
        "relationships": {
          "modules": {
            "data": [
              {
                "type": "module",
                "id": "example::nested1::nested2"
              }
            ]
          }
        }
      },
      {
        "type": "module",
        "id": "example::nested1::nested2",
        "attributes": {
          "name": "nested2",
          "docs": " nested 2\n"
        },
        "relationships": {
          "modules": {
            "data": [
              {
                "type": "module",
                "id": "example::nested1::nested2::nested3"
              }
            ]
          }
        }
      },
      {
        "type": "module",
        "id": "example::nested1::nested2::nested3",
        "attributes": {
          "name": "nested3",
          "docs": " nested 3\n"
        }
      }
    ]
  }

I cut out relevant context from the actual json, so hopefully I didn’t screw it up. As I said, this should be working for traversing down the tree.

and I tried adding something like this to my model, but it doesn’t work. No surprise as I’m pretty much just flailing here:

import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr(),
    modules: DS.hasMany('modules', { inverse: null}),
    parent_module: DS.belongsTo('module', { inverse: 'modules'}),
});

Any way I can do this? I’ve also though, if ember-data can’t handle it, my route could try to look stuff up, since any module belongs to one parent?

Thanks!


#2

Try:

import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr(),
    modules: DS.hasMany('module', { inverse: 'parentModule' }),
    parentModule: DS.belongsTo('module', { inverse: 'modules' }),
});

See: https://guides.emberjs.com/v2.16.0/models/relationships/#toc_reflexive-relations

EDIT: Ah, your server needs send along the parentModule relationship as well. That’s the piece that’s missing. Is that possible for you to add?


#3

Thanks! I had tried that and it wasn’t working.

Oh, that’d be why :slight_smile:

It can be, yeah. What’s that look like, JSON wise?


#4

I’m sorry, aren’t you Steve Klabnik? LOL

Something like:

"data": {
  "type": "crate",
  "id": "example",
  "relationships": {
    "modules": {
      "data": [
        {
          "type": "module",
          "id": "example::nested1"
        }
      ]
    },
    "parent-module": {
      "data": {
        "type": "module",
        "id": "example::whatever1"
      }
    }
  }
},

See: http://jsonapi.org/format/#document-resource-object-relationships


#5

I am, but you know that saying “in theory, theory and practice are the same, but in practice, they’re not?” I’ve found that even with my own spec, sometimes ember-data expects something specific, rather than the way I try to do it. :laughing:

Thanks for the tip, gonna give that a try right now.

EDIT: that seems to work perfectly, thank you! :heart:


#6

Awesome! Happy to help.