Relations

Records from different collections can be related to each other. There are two kinds of relations between collections:

  • One to many. If one record from collection A can be linked with many ones in collection B, but any of records from B can be linked only with single record from A.

  • Many to many. If any record from A can be linked with unlimited number of records from collection B and any B record also can be linked with many records from A too.

Tabbli uses record keys for storing relations inside the database. So, if you work with relations inside templates you can use keys for making requests for fetching additional data. For example, we have some student with relations to particular classes.

You can use the next operator for fetch a record data with particular key:

{% set record = DB().get_collection("students").get_record(key="student-angel-henry").get_dict() %}

The content of record variable here will be like that:

{'attached_images': [{'image': 'images/records/6fb96848-7a02-4f1f-8a1e-fa6010c55da1/69ad9b3f54594da19951c2ea683b73f4.png',
'name': {'en': 'Angel Henry'},
'url': 'https://demo.tabbli.com/media/images/records/6fb96848-7a02-4f1f-8a1e-fa6010c55da1/69ad9b3f54594da19951c2ea683b73f4.png'}],
'children': {'count': 0},
'filtered_properties': ['classes'],
'id': '6fb96848-7a02-4f1f-8a1e-fa6010c55da1',
'important_properties': ['bday', 'email', 'phone', 'classes'],
'key': 'student-angel-henry',
'language': 'en',
'multilingual_properties': [],
'name': {'en': 'Angel Henry'},
'properties': {'bday': datetime.datetime(1991, 1, 6, 0, 0),
'classes': [{'id': 'cd64970d-c395-43a4-bd8e-2c13dd95e38f',
'key': 'class-vessel-planing-with-tabbli',
'name': {'en': 'Vessel planing'}},
{'id': '6997cbb1-ba18-4ef4-adc0-67e1331e9271',
'key': 'class-project-logistics-courses',
'name': {'en': 'Equipment management'}},
{'id': '4c9fc47b-a780-42cc-a29a-2549fdd20479',
'key': 'class-english-at-the-morning',
'name': {'en': 'English at the Morning'}}],
'email': '[email protected]',
'phone': '(252) 555-0126'},
'property_names': {'bday': {'en': 'Date of birthday'},
'classes': {'en': 'Classes'},
'email': {'en': 'Email'},
'phone': {'en': 'Phone'}},
'property_types': {'bday': 'date',
'classes': 'many_to_many',
'email': 'email',
'phone': 'string'},
'record_subsets': [],
'record_type': {'attached_images_support': True,
'children_support_children': False,
'key': 'student',
'name': {'en': 'Student'},
'nested_records_support': False}}

In that example the property with key classes represents a many-to-many relations to another collection "Class". In the structure above you can see that for each link is represented with its id, key and name.

{
'id': '4c9fc47b-a780-42cc-a29a-2549fdd20479',
'key': 'class-english-at-the-morning',
'name': {'en': 'English at the Morning'}
}

So, if you need extra information about related record you can use the proper operator again:

{% set record_class = DB().get_collection("classes").get_record(key="class-english-at-the-morning").get_dict() %}

Result will be like that:

{'attached_images': [],
'children': {'count': 0},
'filtered_properties': ['date', 'up_to', 'time', 'days'],
'id': '4c9fc47b-a780-42cc-a29a-2549fdd20479',
'important_properties': ['course', 'teacher', 'date', 'up_to', 'time', 'days'],
'key': 'class-english-at-the-morning',
'language': 'en',
'multilingual_properties': [],
'name': {'en': 'English at the Morning'},
'properties': {'course': {'id': '533608ee-8d7c-4134-9b34-af7ecb203280',
'key': 'course-english-language',
'name': {'en': 'English Language'}},
'date': datetime.datetime(2019, 11, 4, 0, 0),
'days': 'Mon, Wed',
'teacher': {'id': '71ddfe3c-8bc6-4491-ade6-5978f31675a3',
'key': 'person-brandon-howard',
'name': {'en': 'Brandon Howard'}},
'time': '10:00 - 12:00',
'up_to': datetime.datetime(2020, 5, 1, 0, 0)},
'property_names': {'course': {'en': 'Course'},
'date': {'en': 'Date of starting'},
'days': {'en': 'Days of week'},
'teacher': {'en': 'Teacher'},
'time': {'en': 'Time'},
'up_to': {'en': 'Up to'}},
'property_types': {'course': 'one_to_many',
'date': 'date',
'days': 'string',
'teacher': 'one_to_many',
'time': 'string',
'up_to': 'date'},
'record_subsets': [],
'record_type': {'attached_images_support': False,
'children_support_children': False,
'key': 'class',
'name': {'en': 'Class'},
'nested_records_support': False}}

In management interface you can see automatically created tabs for reverse relations:

Reverse relations to another collection

If you need to do the same in the code you can use filtering:

{% set students_english_morning = DB().get_collection("students").get_filtered_records(filter_data={"f-classes": ["class-english-at-the-morning"]}).records %}

Despite regular collections Tabbli also supports a system structure Users. Because it is a system component, you cannot use the same principles for building relations like with other collections. For working with users, Tabbli supports the next property types:

  • User relation. When a record could be linked with one user.

  • Multiple user relations. When a record could be linked with multiple users.

As a key for relations with users Tabbli uses email. It also means, that email is required and unique property for users. You can also see reverse relations in the manahement interface on a user profile page.