Laurel, I recommend using google to search the mailing lists for questions like this also. There are times (like right now) when I have time to write this email but it's harder to make time to integrate this into the documentation.
Hiroki, Learner data from all membership versions is saved in the SDS but there isn't yet a way to ask for just the data from session bundles for membership version 3 of a workgroup. There could be ... but there isn't right now. Right now researcher report data is based on ALL the valid session bundles for a workgroup and the reports don't specify the specific membership for each item of data. So for example consider this scenario: The membership for Workgroup "Oranges" starts with sail-users A, B, and C and this is followed with three learner sessions where three session bundles are created and delivered back to the SDS after which the membership is changed to C, D, and E and three more learner sessions occur. The reports for researchers (right now) would list the membership of the workgroup as: C, D, and E but would include data from ALL six learner sessions (from sail-users A, B, C, D, and E). While it is not present in the current researcher reports the data to distinguish these differences is preserved. All learner artifacts have directly or indirectly a foreign key pointing to the bundle they were extracted from. In addition the bundles all have a foreign key referring to the workgroup they relate to as well as an attribute specifying the workgroup membership version this bundle relates to. This is implemented by including both the workgroup id and the workgroup membership version in the Bundle Poster URL delivered as a property in the config file to a SAIL to the SAIL EMF Classes managing learner data persistence for a client session. When the bundle is POSTed back the information in the url is used by the SDS to persist the bundle with the correct relationships to it's related resources. Aaron, Updating the SDS confluence doc is great. Please synch any changes you make there with this file: doc/sds_doc_confluence.txt checked into the SDS svn repository. Please feel free to copy relevant content from any of these messages to the documentation also ;-) Laurel and Aaron, Actually there is no way to fully delete a membership in a workgroup once it has been made however you probably should be able to make a new version of the membership consisting of 0 members. I implemented this capability but please read and test my CAVEAT about this below. What appears to be deleting membership in the workgroup (on the web) is really just making a new membership version without some or all of the previous membership. The reason for this implementation is based on the assumption that once someone is a member of a workgroup there could be learner data associated with that specific version of the membership and unless the whole workgroup is deleted (and all the associated data) the SDS will always keep track returned session bundles of learner data in relation to the workgroup membership in existence at the time the learner session was initiated. This is why workgroup membership is versioned. I thought hard about this last August when I expanded the SDS from it's initial version tied to the original SAIL microportal. I kept getting stuck with this part of the domain until I realized that workgroup membership needs to be versioned. Basically I implemented a policy that states you can only throw out everyone's data in a workgroup (by deleting it) you can't just through out a some member's data. Aaron, There is some kind of initial fence post kind of issue with the version number when creating a new workgroup. It doesn't affect any functionality and I can't quite recall how it shows up but if you look at the code carefully and test it you'll see what I mean. Exactly why the web version could make a new membership consisting of the empty set is not clear. I specifically designed it not to allow this. *** New functionality added to the DEV SDS *** 1) I just added an optional version string to the url for workgroup membership. This works in both REST and web access methods. There is no UI exposed for this on the web other then manually suffixing "/<version-number>" onto the end of the url. 2) I also modified the workgroup controller so you can now use the REST API as Laurel wanted to set the workgroup membership to the empty set when creating a new versioned membership (see example further down). *** CAVEAT *** We should find out what happens when an offering is run for workgroup with no active members -- it may not be anything good! What does it mean to collect learner data for a workgroup with no members? The SDS only allows you to run a client session with a reference to a workgroup. Right now if makes no check to see if the membership is empty. It needs to have a rational policy for this case. It certainly makes no sense to save learner data in this situation. The SDS could automatically apply the property that tells the client not to allow saving of learner data when a session config file is generated for a workgroup with a membership consisting of the empty set. The SAIL EMF persistence code may or may not deal well with no learners (it should be tested and checked) and the PAS VLE displays the names of the learners, what does it do when no learner names are available? ************** Here's some testing that shows how versions work with these new features: At the start the membership for workgroup 1354 is empty and it's at version 4: $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:00:25 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 87 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships></workgroup-memberships> Here's the memberships sequencing through previous versions. Version 3 is still the empty set. $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership/3 HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:00:32 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 87 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships></workgroup-memberships> But version 2 has two members: $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership/2 HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:00:36 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 266 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships> <workgroup-membership> <sail-user-id>5373</sail-user-id> </workgroup-membership> <workgroup-membership> <sail-user-id>5372</sail-user-id> </workgroup-membership> </workgroup-memberships> And version 1 once again has a membership consisting of the empty set. $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership/1 HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:00:40 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 87 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships></workgroup-memberships> $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership/0 HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:00:47 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 177 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships> <workgroup-membership> <sail-user-id>1945</sail-user-id> </workgroup-membership> </workgroup-memberships>: I added two members with the web interfaces and here's what it looks like now: $ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:43:07 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 266 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships> <workgroup-membership> <sail-user-id>5373</sail-user-id> </workgroup-membership> <workgroup-membership> <sail-user-id>5372</sail-user-id> </workgroup-membership> </workgroup-memberships> [~/dev/rails/sds]$ OK, now delete them in the new version: $ curl -i -H 'Content-Type: application/xml' -X POST -d '<workgroup-memberships></workgroup-memberships>' http://rails.dev.concord.org/sds/2/workgroup/1354/membership HTTP/1.1 201 Created Date: Sat, 26 May 2007 04:47:01 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Location: http://rails.dev.concord.org/sds/2/workgroup/1354/membership Cache-Control: no-cache Content-Length: 0 And see what's there now: [~/dev/rails/sds]$ curl -i -X GET -H 'Accept: application/xml' http://rails.dev.concord.org/sds/2/workgroup/1354/membership HTTP/1.1 200 OK Date: Sat, 26 May 2007 04:47:06 GMT Server: lighttpd/1.4.11 Content-Type: application/xml Cache-Control: no-cache Content-Length: 87 Connection: close <?xml version="1.0" encoding="UTF-8"?> <workgroup-memberships></workgroup-memberships> Looks good ---------------------------------------------------------------------- I wrote this in last September (so it's a bit out of date) but it might provide some useful background. At 7:39 PM -0400 9/2/06, Stephen Bannasch wrote: >A bit more possible useful info. This background might be helpful if you want >to look more at the ruby code before the documentation re-appears. > >The model files in this dir: > > http://svn.rails.dev.concord.org/svn/sds/trunk/app/models/ > >Have a great deal of easily read info about the relationships between the >objects and how they are setup in the database. This may give you insight into >what elements need to be included when you are creating sds resources. > >For example the workgroup model: > > http://svn.rails.dev.concord.org/svn/sds/trunk/app/models/workgroup.rb > >Is defined like this: > >class Workgroup < ActiveRecord::Base > > set_table_name "sds_workgroups" > > validates_presence_of :portal_id, :offering_id, :portal_token, :name > validates_uniqueness_of :portal_token, :scope => :portal_id > > belongs_to :portal > belongs_to :offering > has_many :workgroup_memberships > has_many :users, :through => :workgroup_memberships do > def version(version) > find :all, :conditions => ['version = ?', version] > end > end > # this creates the following possible search > # members = workgroup.users.version(1) > > before_create :generate_uuid > > def generate_uuid > self.uuid = UUID.timestamp_create().to_s > end > > before_destroy :delete_workgroup_memberships > > def delete_workgroup_memberships > WorkgroupMembership.delete_all(["workgroup_id = ?", self.id]) > end > > def self.find_all_in_portal(pid) > Workgroup.find(:all, :conditions => ["portal_id = ?", pid]) > end > >end > >Ths is a domain-specific language created in classes that inherit from >ActiveRecord::Base. I do not need to specify any sql and this will work with a >number of different databases in assition to mysql. > >Each 'belongs_to' statement declares that a workgroup will be related to the >listed model. So in a workgroup record in the database there will be one field >for the specific portal realm and one for the offering this workgroup is for. >You will never need to specify the portal_id when you create a resource >because it is already specified in the url. > >The 'has_many :workgroup_memberships' statement declares that >workgroup_memberships will relate to a workgroup. > >The 'has_many :users, :through => :workgroup_memberships' statement declares >that workgroup_memberships will also act as a join table connecting workgroups >to users. > >Here's the schema definition for sds_workgroups: > > create_table "sds_workgroups", :force => true do |t| > t.column "portal_id", :integer > t.column "offering_id", :integer > t.column "portal_token", :string, :default => "", :null => false > t.column "name", :string, :limit => 60, :default => "", :null => false > t.column "uuid", :string, :limit => 36, :default => "", :null => false > t.column "version", :integer, :default => 0, :null => false > t.column "created_at", :datetime > t.column "updated_at", :datetime > end > >So the 2 fields portal_id and offering_id are the foreign key references . >ActiveRecord uses a convention that field names ending in '_id' are foreign >key references to tables specified in the first part of the field name. The >field portal_id is specified in the url but you will need to specify the sds >offering_id when you create a workgroup. The two fields created_at and >updated_at are managed by rails and you will never specify them. > >In this model there is no obvious way to tell but you also do not specify uuid >or version. The uuid and the version are created by the sds when the workgroup >is created and the version is incremented everytime you specify a new >workgroup_membership. Right now the version is handled internally by the sds >and in it's communication with the PLR. However because he sds keeps track of >this it knows what group of users were responsible for specific data saved >into the total data saved by a workgroup. This could be used later by a >reporting system. > >Here's the schema definition for workgroup_memberships: > > create_table "sds_workgroup_memberships", :force => true do |t| > t.column "user_id", :integer, :default => 0, :null => false > t.column "workgroup_id", :integer, :default => 0, :null => false > t.column "version", :integer, :default => 0, :null => false > end > >You can tell it's a join table with it's two foreign key references to users >and workrgoups, in addition each join record holds a the version attribute for >that specific relationship. This allows me to the following in ruby to get the >names of members of version 1 of workgroup 2 when running in an sds console >(interactive shell with all the classes and objects for the sds loaded): > >w = Workgroup.find(2) >members = w.users.version(1) >members.each { |m| puts m.name } > >produces: > > Stephen Bannasch > Scott Cytacki > Grace Bannasch > John Smith --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "SAIL-Dev" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/SAIL-Dev?hl=en -~----------~----~----~----~------~----~------~--~---
