New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parent/Child/Nodes relations #3793

Closed
kukoba opened this Issue Jan 31, 2018 · 8 comments

Comments

Projects
None yet
3 participants
@kukoba

kukoba commented Jan 31, 2018

Question: how to work with parent/child relations or node relations in a context of source plugin?

What I need: I'm working on a plugin which loads data from a backend. In backend there are FAQ items and FAQ categories. Between these entities many-to-many relation: each item can be in more than one category and in one category can be more than one items. Both entity type is a complex object: has a lot of fields. So, I need to push these entities to grapql with relations between them and then have the ability to fetch data according to some criteria from grapql on relevant pages.

So, it could be organized by one of following way (in theory):

  1. Add separate fields to each node type (list of objects) during addition of nodes by plugin
  2. Use child/parent properties of nodes during addition of nodes by plugin

But HOW to do that? I've checked documentation, sources, google, but did not find anything meaningful. I will be much appreciated for any help on this question.

@pieh

This comment has been minimized.

Contributor

pieh commented Jan 31, 2018

Parent/child relationship is one to many so it won't fit your use case. You will need to create additional fields in your nodes to create links between between them.

Here's simplified example:

exports.sourceNodes = ({ boundActionCreators, createNodeId }) => {
  // creating nodes data
  const FAQItems = [
    {
      id: createNodeId('faqItemId1'),
      // your data
      internal: { 
        // type, contentDigest
      }
    },
    {
      id: createNodeId('faqItemId2'),
      // your data
      internal: { 
        // type, contentDigest
      }
    },
    {
      id: createNodeId('faqItemId3'),
      // your data
      internal: { 
        // type, contentDigest
      }
    },
  ]

  const FAQCategories = [
    {
      id: createNodeId('faqCategoryId1'),
      // your data
      internal: { 
        // type, contentDigest
      }
    },
    {
      id: createNodeId('faqCategoryId2'),
      // your data
      internal: { 
        // type, contentDigest
      }
    },
  ]

  // creating links between nodes
  // using '<nameOftheField>___NODE` = id (for 1to1) or array (1 to n) of ids of linked nodes

  // 1st faq item belong to both categories:
  FAQItems[0]['categories___NODE'] = [
    FAQCategories[0].id,
    FAQCategories[1].id,
  ]

  // 2nd faq item just to first category
  FAQItems[1]['categories___NODE'] = [
    FAQCategories[0].id,
  ]

  // 3rd faq item just to second category
  FAQItems[2]['categories___NODE'] = [
    FAQCategories[1].id,
  ]

  // and reverse relation to get faq items from categories
  FAQCategories[0]['items___NODE'] = [
    FAQItems[0].id,
    FAQItems[1].id,
  ]
  FAQCategories[1]['items___NODE'] = [
    FAQItems[0].id,
    FAQItems[2].id,
  ]

  // use createNode to finally create nodes
  const { createNode } = boundActionCreators

  // iterate thorugh items and call createNode
}

then you will have categories field in your items nodes and items field in your categories

@kukoba

This comment has been minimized.

kukoba commented Jan 31, 2018

Parent/child relationship is one to many so it won't fit your use case. You will need to create additional fields in your nodes to create links between between them.

yep, it's absolutely clear, just in my case will be already good to have all items related to each category (have relations to one direction [many-to-one])

@pieh Thx a lot!

@kukoba

This comment has been minimized.

kukoba commented Jan 31, 2018

@pieh ,
btw, for parent/child properties will be the same algorithm?

@pieh

This comment has been minimized.

Contributor

pieh commented Jan 31, 2018

@CALLIKA
What do you mean by saying same algorithm? You can't have multiple parents so you couldn't use it in similiar way as in my code example.

@jquense yeah, you can set either single id value for 1-to-1 node linking or array of ids for 1-to-N (tried to state that in my poorly written comment). For problem we try to solve here (many to many) we need array of ids :)

@kukoba

This comment has been minimized.

kukoba commented Jan 31, 2018

@pieh

What do you mean by saying same algorithm? You can't have multiple parents so you couldn't use it in similiar way as in my code example.

no-no, I mean how to specify node parent or node children

@pieh

This comment has been minimized.

Contributor

pieh commented Jan 31, 2018

via https://www.gatsbyjs.org/docs/bound-action-creators/#createNode

const node {
  id: 'something',
  parent: 'id_of_parent',
  children: [
    'id_of_1st_children',
    'id_of_2nd_children'
  ]
  // data and internal fields
}

createNode(node)

(parent and children fields are optional)

or with https://www.gatsbyjs.org/docs/bound-action-creators/#createParentChildLink (if node is created by other plugin)

but this shouldn't really be used to specify that kind of relationship you want here - its more for creating links between nodes that are related to same resource - f.e. when using markdown plugin - markdown nodes set corresponding File nodes as their parents - both nodes are related to single file but one node has fields and functionality related to File and other expand it to allow parsing markdown in those files

@KyleAMathews

This comment has been minimized.

Contributor

KyleAMathews commented Feb 1, 2018

Parent/Child is meant mostly for transformation relations e.g. as @pieh mentioned when a File node is transformed into a MarkdownRemark child node. In retrospect, we should have made this name more specific. Parent/Child links are just a special case of the general idea of node linking. @pieh's suggestion in the first comment looks perfect.

@pieh pieh closed this Feb 6, 2018

@kukoba

This comment has been minimized.

kukoba commented Apr 10, 2018

@pieh, @KyleAMathews, thx a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment