| 12 | |
| 13 | Instead of having several foreign keys for different primary resources, the shared component contains only one foreign key for the link table. |
| 14 | |
| 15 | The primary resource (=instance table) contains the same ''super-key'' field as the component, thus the forward join of resource-to-component can be established as a natural join, i.e. without accessing the link table. |
| 16 | |
| 17 | For the (seldom needed) backward join component-to-resource, the link table needs to be involved because it contains the table name of the primary resource in the field {{instance_type}}. |
| 18 | |
| 19 | Disadvantage of the link table method is that the link table needs to be updated whenever a primary resource record is created, updated or deleted. Thus, it is recommended to not use super-entities for resources where the extra load on write can give a serious performance problem (e.g. messages), or at least to keep the super-entity table lean and free of extra references. |
| 20 | |
| 21 | == API == |
| 22 | |
| 23 | Too simplify the handling of super-entities in the model, S3Model provides a unified API for super-entities: |
| 24 | |
| 25 | === Defining a Super-Entity === |
| 26 | |
| 27 | To define a super-entity, you can use the {{{super_entity()}}} function: |
| 28 | |
| 29 | You can define so-called ''shared fields'' in the super-entity, which are mirrored from the respective resource record. This allows to easily access these data from the component without the need to involve the primay instance table in the backward-join: |
| 30 | |
| 31 | In case the names of the shared fields in your instance table differ from those of the super-entity, you can define a field mapping: |
| 32 | |
| 33 | === Defining an Instance of a Super-Entity === |
| 34 | |
| 35 | To make a table an instance of a super-entity, you can use {{{s3xrc.model.configure()}}}: |
| 36 | |
| 37 | In case your table uses different names for the shared fields, you can additionally set a field mapping: |
| 38 | |
| 39 | === Linking to a Super-Entity === |
| 40 | |
| 41 | Both, instance tables as well as shared components need to be linked to the super-entity. This can be done by inserting a ''super-key'' field into the instance/component table which must have the same name as the primary key of the super-entity. You can use the {{{super_link()}}} function as a DRY method for this: |
| 42 | |
| 43 | === Updating a Super-Entity === |
| 44 | |
| 45 | If you use [wiki:S3XRC/RESTfulAPI/s3_rest_controller s3_rest_controller()] for CRUD, it will automatically create, update and delete super-entities as necessary. |
| 46 | |
| 47 | Otherwise, or if you manipulate records outside s3_rest_controller, you have to update all super-entities which an instance table implements whenever you create, update or delete a record in that table. |
| 48 | |
| 49 | To do this, you can use: |
| 50 | {{{ |
| 51 | s3xrc.model.update_super(table, record) |
| 52 | }}} |
| 53 | |
| 54 | where {{{table}}} is the instance table and {{{record}}} the newly created/updated record. |
| 55 | |
| 56 | In case you're going to delete a record from an instance table, you may use: |
| 57 | {{{ |
| 58 | s3xrc.model.delete_super(table, record) |
| 59 | }}} |
| 60 | |
| 61 | '''before''' you delete the record, where {{{table}}} is the instance table and {{{record}}} the record to be deleted. |