Loading Related Records From an Array Property
The related records
graphql argument can be a really powerful tool that allows you to quickly build flexible structures.
Using foreign_property
along with join_on_property
you can define relationships on the fly and load any nested data within a single query.
We extended the scope of the join_on_property
and now it also accepts and resolves queries with the property of array type.
In this tutorial, you will learn how join_on_property
can be used based on a real scenario.
You will use the new function to build a homepage that presents 3 lists:
- most popular programmers
- most valuable programmers
- and most popular companies
One way of solving this is to create three queries and calculate what to display each time the page is accessed. But this is not recommended, at least on the homepage, as it is the very first page of our site. We have to make sure it loads as quickly as possible.
Moreover, pages based on live queries are hard to customize - imagine you want to add one extra record to be displayed which is not accessible by the query. Then create next query... oh wait. Why is the page so slow?
You need to figure out something better - you need an extra structure.
Requirements
This is an advanced tutorial. To follow it, you should be familiar with Tables, Properties, and Loding Related Records
Steps
Loading related records form an array property following this scenario is a four-step process:
Step 1: Create record type
Create a special record type ranking
.
name: ranking
properties:
- name: name
type: string
- name: company_ids
type: array
belongs_to: company
- name: vip_programmer_ids
type: array
belongs_to: programmer
- name: featured_programmer_ids
type: array
belongs_to: programmer
It consists of three properties of the type array which will serve as cache containers of the homepage lists.
[parameter belongs_to
is currently only used during import/export operations]
Step 2: Create first record
Now create the first record of the ranking
record schema that executes the following query:
mutation createRanking {
record_create(
record: {
table: "ranking"
}
) {
id
}
}
Step 3: Populate ranking record
You are now ready to populate the ranking record.
mutation updateRecord($companies: [String], $vips: [String], $featured: [String]) {
record_update(
id: 167655
record: {
properties: [
{
name: "company_ids",
value_array: $companies
},
{
name: "vip_programmer_ids"
value_array: $vips
},
{
name: "featured_programmer_ids",
value_array: $featured
}
]
}) {
id
}
}
Alternatively, you can add a single ID to a specific field with the following query:
mutation updateRecord($name: String!, $id: String) {
record_update(
id: 167655
record: {
properties: [
{ name: $name, array_append: $id }
]
}) {
id
property_array(name: $name)
}
}
If you want to remove an element from an array use: array_remove
.
Step 4: Fetch ranking record
Finally you are ready to fetch the ranking record.
query rankings {
rankings: records(
per_page: 1,
sort: {
created_at: { order: DESC }
},
filter: {
name: { value: "ranking" }
}
) {
results {
vips: related_records(
join_on_property: "vip_programmer_ids",
foreign_property: "id",
table:"programmer"
) {
name: property(name: "name")
}
featured: related_records(
join_on_property: "featured_programmer_ids",
foreign_property: "id",
table:"programmer"
) {
name: property(name: "name")
}
companies: related_records(
join_on_property: "company_ids",
foreign_property: "id",
table:"company"
) {
name: property(name: "name")
}
}
}
}
As a result, you will get a ranking record filled with nested objects - featured programmers and popular companies - ready to be presented on the page.
Your homepage - backed up by really simple structure - will load much faster, because it is only one query.
In addition (even though you added some extra code) the final solution is clearer than a complex query and easier to maintain and extend.