Computed foreign keys
Displaying a link to the last message sent by a customer
from forestadmin.datasource_toolkit.context.collection_context import (
CollectionCustomizationContext,
)
from forestadmin.datasource_toolkit.interfaces.fields import Operator
from forestadmin.datasource_toolkit.interfaces.query.aggregation import (
Aggregation,
Aggregator,
)
from forestadmin.datasource_toolkit.interfaces.query.condition_tree.nodes.base import (
ConditionTree,
)
from forestadmin.datasource_toolkit.interfaces.query.condition_tree.nodes.leaf import (
ConditionTreeLeaf,
)
from forestadmin.datasource_toolkit.interfaces.query.filter.unpaginated import Filter
from forestadmin.datasource_toolkit.interfaces.records import RecordsDataAlias
async def get_last_message_id(
customers: RecordsDataAlias, context: CollectionCustomizationContext
):
# We're using Forest Admin's Query Interface (you can use an ORM or plain SQL)
messages = context.datasource.get_collection("messages")
condition_tree = ConditionTreeLeaf(
"customer_id", Operator.IN, [c["id"] for c in customers]
)
rows = await messages.aggregate(
context.caller,
Filter({"condition_tree": condition_tree}),
Aggregation(
{
"field": "id",
"operation": "Max",
"groups": [{"field": "customer_id"}],
}
),
)
ret = []
for customer in customers:
row = filter(lambda r: r["group"]["customer_id"] == customer["id"], rows)
row = row[0] if len(row) == 1 else {}
ret.append(row.get("value"))
return ret
async def last_message_in_operator(
last_message_ids: List[Any], context: CollectionCustomizationContext
) -> ConditionTree:
records = await context.datasource.get_collection("messages").list(
context.caller,
Filter(
{
"condition_tree": ConditionTreeLeaf(
"id", Operator.IN, last_message_ids
)
}
),
["customer_id"],
)
return ConditionTreeLeaf("id", Operator.IN, [r["customer_id"] for r in records])
agent.customize_collection("Customers").add_field(
"lastMessageId",
{
# Create foreign key
"column_type": "Number",
"dependencies": ["id"],
"get_values": get_last_message_id,
},
).replace_field_operator(
# Implement the 'In' operator.
"lastMessageId",
Operator.IN,
last_message_in_operator,
).add_many_to_one_relation(
# Create relationships using the foreign key we just added.
name="lastMessage",
foreign_collection="messages",
foreign_key="lastMessageId",
)Connecting collections without having a shared identifier
Last updated