Changes between Initial Version and Version 1 of JoinedResourceController


Ignore:
Timestamp:
09/06/09 23:12:33 (16 years ago)
Author:
Dominic König
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • JoinedResourceController

    v1 v1  
     1[[TOC]]
     2
     3= Joined Resource Controller =
     4
     5  * Code: [https://code.launchpad.net/~flavour/sahana/sahanapy-trunk Main Trunk] Revision 275+
     6
     7The '''Joined Resource Controller''' provides a RESTful API for joined resources analogous to the generic [wiki:BluePrintRESTImplementation shn_rest_controller].
     8
     9A joined resource request is a request on a resource ("joined resource") in dependence of a join to another table ("primary resource").
     10
     11In this implementation, these joins can be 1:1 or 1:N, and they can be natural joins (same key field in both tables) or primary/foreign key matches, where the primary key is always the 'id' field in the primary table.
     12
     13The controller function for this is:
     14
     15    * '''shn_jr_rest_controller''' (defined in models/01_jr_controller.py)
     16
     17== Model ==
     18
     19Example for definition of a joined resource in the model:
     20
     21{{{
     22resource = 'image'
     23table = module + '_' + resource
     24db.define_table(table, timestamp, uuidstamp, deletion_status,
     25                pr_pe_id,
     26                opt_pr_image_type,
     27                Field('title'),
     28                Field('image', 'upload', autodelete=True),
     29                Field('description'),
     30                Field('comment'),
     31                migrate=migrate)
     32
     33# Joined Resource
     34jrlayer.add_jresource(module, resource,
     35    multiple=True,
     36    joinby='pr_pe_id',
     37    fields = ['id', 'opt_pr_image_type', 'image', 'title','description'])
     38}}}
     39
     40where:
     41
     42  - '''module''' is the name of the module in which the joined resource is defined (prefix)
     43  - '''resource''' is the name of the joined resource
     44  - '''multiple''' indicates whether this is a 1:N (True) or 1:1 (False) join, defaults to True
     45  - '''joinby''' describes the join keys:
     46    - pass a single field name for natural joins (same key field in both tables)
     47    - pass a dictionary of ''tablename=fieldname'' pairs for primary/foreign key matching, in which:
     48      - ''tablename'' is the name of the respective primary table
     49      - ''fieldname'' the name of the foreign key in the joined table that points to the ''id'' field in the primary table
     50  - '''fields''' is a list of the fields in the joined resource that shall appear in list views:
     51    - if omitted or set to None, all readable fields will be included
     52
     53No definitions are required at the primary resource, just define the table as usual.
     54
     55  - Of course, shn_jr_rest_controller is sensitive to the deletion status
     56
     57== Controller ==
     58
     59shn_jr_rest_controller takes (almost) the same settings and arguments as shn_rest_controller:
     60
     61{{{
     62def person():
     63    crud.settings.delete_onvalidation=shn_pentity_ondelete
     64    return shn_jr_rest_controller(module, 'person', main='first_name', extra='last_name',
     65        pheader=shn_pr_pheader,
     66        onvalidation=lambda form: shn_pentity_onvalidation(form, table='pr_person', entity_class=1),
     67        onaccept=None)
     68}}}
     69
     70"Almost" means with exception of the optional '''pheader''' argument: This helps you to display some information about the primary resource record in the view while operating on a joined resource (e.g. the person's name and ID, when displaying a list of available images for this person). You may pass static content, or a function or lambda to produce content, which is to be forwarded as ''pheader'' variable to the view.
     71
     72If you pass a function or lambda, it has to take 5 arguments:
     73  - '''resource''' = name of the primary resource
     74  - '''record_id''' = id of the primary resource record
     75  - '''representation''' = data format of the request
     76  - '''next=None''' = backlink URL to reproduce the request (with empty method)
     77  - '''same=None''' = backlink URL to reproduce the request (with empty method and containing the string '[id]' instead of the primary resource record id)
     78
     79These backlinks can be used to reproduce the original request after doing something on the primary resource (e.g., edit or change the selected record).
     80
     81  * '''NOTE:''' Callbacks from CRUD settings (like in the example above) as well as onvalidation and onaccept callbacks are only invoked at requests on the main resource, but not at joined requests.
     82
     83== Argument Lists ==
     84
     85URL format:
     86
     87{{{
     88http://host/application/module/resource/<arguments>?<vars>
     89}}}
     90
     91The argument list is interpreted as follows:
     92
     93  * '''empty argument list''' is a LIST attempt to the primary resource
     94  * '''<id>''' is a READ attempt on the record #<id> of the primary resource
     95  * '''<method>''' is a <method> attempt on the primary resource
     96  * '''<method>/<id>''' is a <method> attempt on the record #<id> of the primary resource
     97  * '''<id>/<joined_resource>''' is a LIST attempt to the joined resource for the record #<id> of the primary resource
     98  * '''<joined_resource>?id_label=XXX''' is a LIST attempt to the joined resource for the record of the primary resource with that label
     99  * '''<id>/<joined_resource>/<method>''' is a <method> attempt on the joined resource for the record #<id> of the primary resource
     100  * '''<joined_resource>/<method>?id_label=XXX''' analogous.
     101
     102You may even pass the record ID of the joined resource at the end of the arguments list to access a particular record - which would produce an error message if these two records do not belong together.
     103
     104== Plug-In Resource Actions ==
     105
     106You may plug in custom resource actions to shn_jr_rest_controller, e.g. if you have a custom search function for a resource.
     107
     108Example:
     109This adds a ''search_simple'' method to the ''person'' resource, which calls the ''shn_pr_person_search_simple'' function:
     110
     111{{{
     112# Plug into REST controller
     113jrlayer.set_method(module, 'person', None, None, 'search_simple', shn_pr_person_search_simple )
     114}}}
     115
     116Arguments of jrlayer.set_method:
     117
     118  * '''module''' = name of the module of the primary resource
     119  * '''resource''' = name of the primary resource
     120  * '''jmodule''' = name of the module of the joined resource (if any, maybe None)
     121  * '''jresource''' = name of the joined resource (if any, maybe None)
     122  * '''method''' = name of the method
     123  * '''action''' = the function or lambda to invoke for that method (to remove a plug-in action, just pass None here)
     124
     125The action method in turn has to take plenty of arguments:
     126
     127  * '''module'''
     128  * '''resource'''
     129  * '''record_id'''
     130  * '''method'''
     131  * '''jmodule=None'''
     132  * '''jresource=None'''
     133  * '''jrecord_id=None'''
     134  * '''joinby=None'''
     135  * '''multiple=True'''
     136  * '''representation="html"'''
     137  * '''onvalidation=None'''
     138  * '''onaccept=None'''