| | 9 | == Link-Table Components == |
| | 10 | |
| | 11 | Components can be bound to their master records via link-tables. In such cases, the foreign key constraints for the component link are all in a separate link-table, whereas both the master table and the component table are completely independent: |
| | 12 | |
| | 13 | {{{ |
| | 14 | master (primary key) <==== (foreign key) link table (foreign key) ====> (primary key) component |
| | 15 | }}} |
| | 16 | |
| | 17 | Link-table component links have some advantages over simple foreign key constraints: |
| | 18 | |
| | 19 | - they can carry attributes of their own (qualified link) |
| | 20 | - they provide the option to bind the same component record to multiple master records (many-to-many) |
| | 21 | - there are several different ways to actuate such links |
| | 22 | |
| | 23 | However, they do have disadvantages too: |
| | 24 | |
| | 25 | - overhead to maintain a separate database table (processing time, migration issues etc.) |
| | 26 | - increased complexity to access and query resources (3 tables instead of 2) |
| | 27 | - increased complexity to handle such links in CRUD and XML/XSLT |
| | 28 | |
| | 29 | === Link Actuation Methods === |
| | 30 | |
| | 31 | With link-table component links, you have several different methods available to "actuate" the link. That is, RESTful methods can operate either on the link table, on the component table or both - depending on the request method and the link configuration. The basic "actuation" methods are: |
| | 32 | |
| | 33 | - ''replace'': hides the link table and always operates on the component table |
| | 34 | - ''hide'': hides the component table and always operates on the link table |
| | 35 | - ''link'': operates on the component table for single-record requests, and on the link table for summary requests (=without record ID) and delete |
| | 36 | - ''embed'': operates on the link table, embeds the component record in single-record requests |
| | 37 | |
| | 38 | The following table gives an overview over link actuation in S3CRUD: |
| | 39 | |
| | 40 | ||=Link Actuation Method=||='''replace'''=||='''hide'''=||='''link'''=||='''embed'''=|| |
| | 41 | ||=CRUD Method=||= =||= =||= =||= =|| |
| | 42 | ||='''create'''=|| create-form for component || create-form for link || create-form for link || create-form for link with component embedded || |
| | 43 | ||='''read'''=|| read view of component || read view of link || read-view of component || read-view of link (with component embedded^2^) || |
| | 44 | ||='''update'''=|| update-form for component || update-form for link || update-form for component || update-form for link with component embedded || |
| | 45 | ||='''delete'''=|| deletes both, component and link || deletes the link|| deletes the link^1^ || deletes the link^1^ || |
| | 46 | ||='''list'''=|| list view of component || list view of link || list view of link || list view of link (with component embedded^2^) || |
| | 47 | |
| | 48 | * ^1^ = deletes the component together with the last link if ''autodelete'' option is set |
| | 49 | * ^2^ = not implemented yet |
| | 50 | |
| | 51 | Other RESTful methods such as S3Search or S3Cube may have their own definitions. |
| | 52 | |
| | 53 | === Declaration === |
| | 54 | |
| | 55 | The basic syntax of a link-table component link declaration is: |
| | 56 | |
| | 57 | {{{ |
| | 58 | s3mgr.model.add_component("my_component", # Tablename of the component |
| | 59 | my_master=dict( # Tablename of the master table |
| | 60 | link="my_linktable", # Tablename of the link table |
| | 61 | joinby="fieldname", # FK of the master table (=left key constraint) |
| | 62 | key="fieldname", # FK of the component table (=right key constraint) |
| | 63 | actuate="replace", # Actuation method (see above, optional, defaults to "link") |
| | 64 | autodelete=False # Delete the component record together with the last link (optional, default is False) |
| | 65 | widget=Widget, # Widget to use for embedding (optional, defaults to S3EmbedComponentWidget) |
| | 66 | autocomplete="fieldname", # Field in the component to use for autocomplete when embedding the component |
| | 67 | )) |
| | 68 | |
| | 69 | }}} |
| | 70 | |
| | 71 | If no field is defined for ''autocomplete'', then no autocomplete-widget will be used, but a standard SELECT of options for ''key'' (default behavior). |
| | 72 | |
| | 73 | Important: if you specify a widget for embedding (e.g. S3AddPersonWidget), then you must not use this widget or a widget validator for the right key constraint! |
| | 74 | |