Forum .LRN Q&A: Implementing class membership quota

Posted by Radam Batnag on
I want to limit the number of students that can join a class, without
imposing an additional burden on the site admins or the class admins.
I also want to keep class membership policies "open", not "Needs
Approval" or "Closed".

The most straightforward approach I can think of is to store quotas in
a separate table, and create a before insert trigger on on acs_rels.
The trigger will check if the insert operation is trying to create a
dotlrn_student_rel relation, and if it is, it will check first the
class quota table to determine if the class is not yet full, before
allowing the insert to proceed.

The problem with this approach is that it imposes a
burden on many other relationship-related operations, even non-dotLRN
ones. Any suggestions on who to implement this efficiently AND without
having to modify dotLRN (so that this could be an optional package)?

Posted by Peter Marklund on
Radam, the trigger may be a good idea to enforce the max number of students for a class. However, I imagine that you will want to check the number of students before the addition of the student is even attempted so that you can give the user a message explaining why he/she can't join the class.

The ability to limit the number of students for a class seems like a general enough requirement that it would warrant being in the dotLRN datamodel. From a quick glance at classes-create.sql and communities-create.sql the dotlrn_communities_all table suggests itself as a candidate for putting a max_n_members column in.

Posted by Carl Robert Blesius on
I would like to second that... it does seem like a general enough requirement to be part of dotLRN (in fact I can think of a couple of classes we run on our present platform where that would be VERY useful).
Posted by Caroline Meeks on
I like this idea.

Here is a use case I think Sloan would want to use.

The Instructor wants to divide the class into teams of 3-4 to work on projects. He sets up a group for each project topic and sets the maxium membership to 4.

For implementation, I would suggest not enforcing the membership cap too strictly.  In general everything in education is subject to exceptions based on the instructors whim and it should be expected that the instructor will occasionally allow extra students in.

My first thought would be to have the logic that presents a join/request link check against the membership quota and change join to request if the class(or other type of dotlrn_community) is full.

Here is an example of why I suggest this implementation using the use case above

A 5th student presents the instructor with a compelling reason why he in particular should be allowed to join a full group. The instructor  adds him through the control panel manage membership link and does not have to change the max_membership of the group. Thus, if another student in this group drops the class, bringing this group back down to 4, the project is still closed to new members.

Alternatively, the students in a specific project could convince the instructor that their topic was especially complex and needed a larger group and thus another person should be allowed to join. In this case the instructor would increase the max_members and if one of the existing students dropped out the group would again show as open for new members.

Posted by Peter Marklund on
Caroline, the use-cases you are describing make a lot of sense to me. I think they are generic enough that they should be implemented both in the Sloan and the dotLRN sources.
Posted by Radam Batnag on

My intent is to build a full-blown online enrollment system for dotLRN. Obviously, one of the core requirements of such a system would be to prevent too many students from enrolling in a class, hence the membership quota. (Other requirements would be to assign fees to classes, assess student dues, and interface with an accounting system - but the discussion for these belong to another thread.)

I thought it's a specialized requirement, I didn't realize that it's a use case wide enough to be implemented dotLRN-wide.

To sum up the discussion so far: we want a generic facility for setting dotLRN community membership quotas. The quota is a restriction that applies only to member-initiated "join community" operations; admins can override this through the "add member" facility.

Peter, thanks for the datamodel tip. I'll start digging in to the dotLRN sources.

Posted by Ben Adida on
Class membership quotas sound like a great idea.

Triggers on acs_rels, on the other hand, give me a bad headache reminiscent of ACS 3.x education package which had triggers all over the user table - which made modularity completely impossible in the end.

If you want to implement this using triggers, you should make sure the triggers are created and applied to tables within the same package. For example, you might add a trigger to dotlrn_student_rels. Or you can do some tricky locking using select for update when you're about to add a student. Either way, make sure it's something that is well contained to the dotLRN package itself.

Posted by Emmanuelle Raffenne on

just to say that, at UNED, we use class quotas. We implemented it in the ACES platform and we plan to use it too with dotLRN. It would be very good news if it will be included :)

Posted by Radamanthus Batnag on
I've created a preliminary version of this.

What I've done

max_n_members is a property of dotlrn_community_types,
and is inherited by dotlrn_communities. i.e. you can
set a per-subject membership limit, and all class instances
of that subject will have by default the same membership limit.

For subjects, the value for max_n_members is set through the "edit subject properties".
For communities and class instances, the value is set through the edit community properties" pages.

max_n_members applies to all dotlrn communities.

if, for a particular community, max_n_members = 0 or is null, no membership limit will be enforced for that community.

How I did it

1. modify the data model:
  - add max_n_members column to dotlrn_community_types
  - add max_n_members column to dotlrn_communities_all
  - created additional *__new stored procedures for dotlrn_community_types and dotlrn_communities_all
  (I only did a PostgreSQL version)
  - created a new table: dotlrn_community_mem_rel_tracking, to track community memberships
  - created before insert and after delete triggers on dotlrn_member_rels, to keep dotlrn_community_mem_rel_tracking up-to-date

2. modify the tcl (and xql) procs:
  - community-procs.tcl: added get_* and set_* procs for max_n_members and mem_count

3. modify the UI - added a form field for max_n_members in the following add/edit pages:
  - community-edit.tcl
  - /dotlrn/admin/class-edit.tcl
  - /dotlrn/admin/class-instance-new.tcl
  - /dotlrn/admin/class-new.tcl

4. enforce the max. membership rule
  - /dotlrn/register.tcl: added a select...for update lock that checks to make sure that the max. membership
  rule will not be exceeded if the user joined the community

5. reinstall dotLRN (to recreate the views affected by step #1)

Please help me...

1. Suggest better ways of implementing this
2. Suggest ways on how to test this (I only tested this using simultaneous mouse clicks on two separate computers)