How to connect Many-to-one relations in FaunaDB

Viewed 152

I’ve got the following GraphQL schema uploaded to my FaunaDB:

type RSheet @collection(name: "sheets") {
  columns: [RColumn!]! @relation
  sections: [RSection]!
}

type RColumn @collection(name: "columns") {
  label: String!
  sheet: RSheet!
}

type RSection @embedded {
  label: String
  items: [[RItem!]]!
}

type RItem @embedded {
  value: String
  form: RItemForm
  column: RColumn!
}

enum RItemForm {
  STRING
}

That is a sheet with columns and a number of sections with items that make the rows of a table.


Now, I’ve created a sheet as well as two columns.

“sheets” collection in the database

{
  "ref": Ref(Collection("sheets"), "304268724760740364"),
  "sections": [
    {
      "label": null,
      "items": []
    }
  ]
}

“columns” collection in the database

{
  "ref": Ref(Collection("columns"), "304268724764934668"),
  "label": "Begin",
  "sheet": Ref(Collection("sheets"), "304268724760740364")
},
{
  "ref": Ref(Collection("columns"), "304268724776469004"),
  "label": "End",
  "sheet": Ref(Collection("sheets"), "304268724760740364")
}

All this works fine so far. I can create sheets and/or columns, update, and delete them.


However, if I want to add a section item using FaunaDB’s GraphQL I can’t connect the item’s columns. I get an error stating that I have to provide the column’s ID!:

Screenshot of the GraphQL error

When I do so, only the ID is written to the database and a connection Ref(…) is not created:

“sheets” collection in the database

{
    "ref": Ref(Collection("sheets"), "304268724760740364"),
    "sections": [
      label: null
      {
        "items": [
          [
            {
              "value": "Item 1",
              "column": "304268724791149068"  /// EXPECTED: Ref(Collection("columns"), "304268724791149068")
            }
          ]
        ]
      }
    ]
  }

What am I missing?

1 Answers

You cannot create relations inside embedded types. From the docs on relations:

The relationship recognition algorithm looks at every field for all non-embedded types

I do think it would be nice to have relationships work through @embedded types, but that is not what they were really intended for, so it is not supported.

You will need to rework your schema so that each connection is in an non-embedded type. Also, the 2-dimensional array is also not possible with connections.

Example

Consider the following schema

type RSheet @collection(name: "sheets") {
  columns: [RColumn!]! @relation
  sections: [RSection]! @relation
}

type RColumn @collection(name: "columns") {
  label: String!
  sheet: RSheet! @relation
  items: [RItem!] @relation
}

type RSection @collection(name: "section") {
  label: String
  sheet: RSheet @relation
  items: [RSectionItemList!]! @relation
}

type RSectionItemList @collection(name: "section_item_list") {
  section: RSection! @relation
  items: [RItem!]! @relation
}

type RItem @collection(name: "item") {
  value: String
  form: RItemForm
  column: RColumn! @relation
  list: RSectionItemList @relation
}

enum RItemForm {
  STRING
}

Note how I split the 2-dimensional array into a list of wrapper list objects.

A sheet and columns could be created like this:

enter image description here

And items added like this:

enter image description here

Related