[SSF] Members for tasks

Added an "Interested" field that would show up in the rheader/form for Tasks, and users can 'Watch' a task(i.e, assign themselves a 'following' role). However, deployment settings can be changed to allow Users to assign themselves other roles such as "Mentor", "Volunteer" that shows up as a dropdown-list along with the "Watch" button.

Indeed, you could use the existing web services to create/delete/update the role assignment - without the custom method handler. That requires a bit more thinking, but less code - and delivers the authorization out of the box.

But I know you wanted to do this exercise, and it is good if you learn how custom methods can be build.

NB: There is also a framework way to define method handlers.

You define a function as method handler:

    def assign_role(r, **attr):
        if r.method == "assign":
            # code for assignment
        elif r.method == "remove":
            # code to remove assignment

As an S3Method, it would look like this:

    class TaskRoleManagement(S3Method):

        def apply_method(self, r, **attr):
            if r.http == "POST":
                if r.method == "assign":
                    self.assign_role(r, **attr)
                elif r.method == assign
                    self.remove_role(r, **attr)
                r.error(405, current.ERROR.BAD_METHOD)

        def assign_role(self, r, **attr):
             # Code to assign a role

        def remove_role(self, r, **attr):
             # Code to remove a role assignment

And then like before:

    s3db.set_method("project", "task", method="assign", action=TaskRoleManagement)
    s3db.set_method("project", "task", method="remove", action=TaskRoleManagement)

Of course, that may be a bit too much for this particular case - I'm just outlining it for your learning. The advantage of S3Method is that the base class already implements a lot of the logic for interactive views (e.g. rheader, safe forwarding, crud-strings etc.) in a consistent, generic way. However, this particular case is just Ajax, and doesn't need any of this, so a function is fine here.