adds content for many-to-many relationships (#807)

This commit is contained in:
dsandip 2018-10-18 19:57:00 +05:30 committed by Shahidh K Muhammed
parent 405f5edb34
commit 82e8d45bf9

View File

@ -9,7 +9,10 @@ Relationships can be of two types:
- one-to-many or ``array relationships``. For example, one author can write many articles
Each relationship has a name which is used to refer to the nested objects in queries. For example, "``articles``" of
an ``author`` and "``author``" of an ``article``
an ``author`` and "``author``" of an ``article``.
.. note::
You can also simulate many-to-many relationships by creating what are typically known as ``bridge`` or ``through`` tables. See :ref:`many-to-many-relationships`
Creating relationships
----------------------
@ -241,6 +244,124 @@ Here are examples to create relationships using the two methods:
}
}
.. _many-to-many-relationships:
Many-to-many relationships
^^^^^^^^^^^^^^^^^^^^^^^^^^
Many-to-many relationships can be simulated by creating tables typically called as ``bridge`` or ``through`` or ``joining`` tables. Let's use a different example from the one above to create such a relationship - say your schema has products and categories. A product can belong to many categories and each category can have many products. Our objective is to fetch a list of products and the possibly many categories each product belongs to.
**Create bridge or through table**
This is the intial schema we are working with:
.. code-block:: sql
product (
id INT PRIMARY KEY,
prod_name TEXT
)
category (
id INT PRIMARY KEY,
cat_name TEXT
)
To capture the association between products and categories, we'll create the following table:
.. code-block:: sql
products_categories (
id INT PRIMARY KEY,
product_id INT,
category_id INT
)
This table sits between the two tables involved in the many-to-many relationship and captures possible permutations of their association. Next, we'll link the data in the ``product`` and ``category`` tables via the bridge table.
**Add foreign-key constraints**
Add the following constraints:
- ``products_categories`` :: ``product_id`` -> ``product`` :: ``id``
- ``products_categories`` :: ``category_id`` -> ``category`` :: ``id``
**Add relationships**
Add the following relationships:
- modify the ``product`` table to add an array relationship between ``products_categories`` :: ``product_id`` -> ``id``, named ``prod_categories``.
- modify the ``products_categories`` table to add an object relationship between ``category_id`` -> ``category`` :: ``id``, named ``category``.
We can now fetch a list of products and a list of categories each product belongs to by leveraging the above relationships:
.. graphiql::
:view_only:
:query:
query {
product {
id
prod_name
prod_categories {
category {
cat_name
}
}
}
}
:response:
{
"data": {
"product": [
{
"id": 1,
"prod_name": "pencil",
"prod_categories": [
{
"category": {
"cat_name": "stationary"
}
},
{
"category": {
"cat_name": "weapon"
}
}
]
},
{
"id": 2,
"prod_name": "bottle",
"prod_categories": [
{
"category": {
"cat_name": "kitchen"
}
}
]
}
]
}
}
If you need to fetch a list of categories and a list of products belonging to each category, you just have to create the relationships the other way around i.e. in ``category`` table, an array relationship between ``products_categories`` :: ``product_id`` -> ``id`` and in the ``products_categories`` table, an object relationship between ``product_id`` -> ``product`` :: ``id``.
The intermediate join table is important as you might add more columns to it over time. For example, the ``products_categories`` table may have a column like ``created_at``. So, the above query then changes to:
.. code-block:: graphql
query {
product {
id
prod_name
prod_categories {
created_at,
category {
cat_name
}
}
}
}
Renaming relationships
----------------------