[[TOC]] [wiki:S3] | [wiki:S3XRC/ModelExtensions Model Extensions] | Component Resources = Component Resources = [[Image(ComponentTypes.png)]] == Link-Table Components == 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: {{{ master (primary key) <==== (foreign key) link table (foreign key) ====> (primary key) component }}} Link-table component links have some advantages over simple foreign key constraints: - they can carry attributes of their own (attributed link) - they provide the option to bind the same component record to multiple master records (many-to-many) - there are several different ways to actuate such links - link-table links work both ways (i.e. with master/component exchanged, can be declared both ways at the same time) However, they do have disadvantages too: - overhead to maintain a separate database table (processing time, migration issues etc.) - increased complexity to access and query resources (3 tables instead of 2) - increased complexity to handle such links in CRUD and XML/XSLT === Link Actuation Methods === When using a link-table to link a primary resource to its components, the RESTful methods can handle this in a number of different ways, depending on the CRUD method and the configuration setting: - ''replace'': hides the link table and always operates on the component table - ''hide'': hides the component table and always operates on the link table - ''link'': operates on the component table for single-record requests, and on the link table for summary requests (=without record ID) and delete - ''embed'': operates on the link table, embeds the component record in single-record requests The following table gives an overview over link actuation in S3CRUD: ||= CRUD Method =||||||||= Link Actuation Method =|| ||= =||='''replace'''=||='''hide'''=||='''link'''=||='''embed'''=|| ||='''create'''=|| create-form for component || create-form for link || create-form for link || create-form for link with component embedded || ||='''read'''=|| read view of component || read view of link || read-view of component || read-view of link (with component embedded^2^) || ||='''update'''=|| update-form for component || update-form for link || update-form for component || update-form for link with component embedded || ||='''delete'''=|| deletes both, component and link || deletes the link || deletes the link^1^ || deletes the link^1^ || ||='''list'''=|| list view of component || list view of link || list view of link || list view of link (with component embedded^2^) || * ^1^ = deletes the component together with the last link if ''autodelete'' option is set * ^2^ = not implemented yet Other RESTful methods such as S3Search or S3Cube may have their own definitions. === Declaration === The basic syntax of a link-table component link declaration is: {{{ s3mgr.model.add_component("my_component", # Tablename of the component my_master=dict( # Tablename of the master table link="my_linktable", # Tablename of the link table joinby="fieldname", # FK of the master table (=left key constraint) key="fieldname", # FK of the component table (=right key constraint) actuate="replace", # Actuation method (see above, optional, defaults to "link") autodelete=False # Delete the component record together with the last link (optional, default is False) widget=Widget, # Widget to use for embedding (optional, defaults to S3EmbedComponentWidget) autocomplete="fieldname", # Field in the component to use for autocomplete when embedding the component )) }}} If no field is defined for ''autocomplete'', then no autocomplete-widget will be used, but a standard SELECT of options for ''key'' (default behavior). 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! ---- DeveloperGuidelines