MarkUs Blog

MarkUs Developers Blog About Their Project

Archive for the ‘schema’ tag

Meeting Minutes: March 5, 2010

with one comment

Brian Xu

  • There’s a question about refactoring the FlexibleCriteria treatment to avoid if “rubric”/else statements.  Karen suggests that, since it’s a relatively complicated question, it be deferred to the end of the meeting
  • Uploaded some new screenshots to ReviewBoard to display FlexibleCriteria functionality
  • For FlexibleCriteria, a valid mark x is a float/integer where 0<=x<=max
  • Victoria should play with the new FlexibleCriteria interface when it’s added to ReviewBoard, to give her input

Bryan Shen

  • Karen thanks Bryan for his help with the dropdown problem experienced at UWaterloo
  • Has been writing tests for FlexibleCriteria – ran into a problem with lots of repeated code
  • Found an elegant solution to the above problem after posting a question on StackOverflow
  • Will work on mapping TAs to marking scheme elements after finishing FlexibleCriteria
  • Mike notes that, realistically speaking, work on mapping TAs to marking scheme elements will probably not get too far before term ends – should focus on foundation work and documentation for next developers to work on it
  • Karen will get the specs for mapping TAs to marking scheme elements to Bryan sometime this weekend

Farah Juma

  • The student interface for the GradeEntryForms is in pretty good shape now
  • Just needs to add ability to release/unrelease marks, CSV upload/download, and tests
  • Mike and Karen want a sneak preview so they can try it out

Joseph Mate

  • Has put up a review request to switch submissions table from AJAX to server-side paginate
  • Did some review requests, and wrote a blog post
  • Next steps include testing, cleaning up the code to take advantage of will_paginate, possibly moving GradeEntryForm to server-side paginate, and getting the detailed submissions table view working again
  • Mike notes that the old functions for the detailed table should still exist, and that getting it going again should (hopefully) not be too hard

Robert Burke

  • Is putting test conversion to Shoulda off to one-side – taking longer than expected (has to rewrite many tests from scratch), and wants to focus on Notables instead
  • Mike notes that it’d be a good general rule of thumb to avoid writing any new tests with Fixtures, but that converting old tests from Fixtures is a task that can be put off for a little while

Karen Reid

  • Checks to ensure that everybody got their midterm report up on UCOSP blog
  • Thanks to everybody who helped out with UWaterloo bugs this week!
  • Classes at UofT end on April 1st.  End on April 5th for UWaterloo, and April 16 for SFU.
  • Karen expects 4 more weeks of work from each team member, but is happy to see it stretch into April if needs be (marks will be sent to schools by end of April)
  • Soft end-date for work is April 1st.  Brian Xu, Bryan Shen, and Robert Burke might continue working.
  • Byron (UWaterloo) is coming to UofT on April 9th to discuss MarkUs plans – all are invited to attend

Brian Xu’s Database Question

  • Original proposals for FlexibleCriteria from Laval students
  • Brian explains the current situation:  In its current implementation, a method “get_criteria” has been added to Assignment model to retrieve collection of criteria (either Flexible or Rubric)
  • Mike thinks it’d be a good idea to try to merge Flexible and Rubric tables into a single Criteria table, and then use Single Table Inheritance to let Assignments / Grader View / View Marks views be ignorant of which marking scheme is being used
  • We are unable to find a scenario which breaks this model
  • The design plan is approved – but delayed until the summer.  Brian Xu / Bryan Shen will continue developing so as to only support Rubric and Flexible Criteria.  Refactoring will happen afterwards.

Written by m_conley

March 6th, 2010 at 1:03 pm

Rebooting the Schema (part 2)

with 2 comments

Last time, I talked about the old model schema, and the problems it had that lead us to refactor the code. After refactoring, this is what the database looks like:

Association

The relationships are now more concrete with the addition of memberships and assignments_groups tables. The assignments_groups is a Rails convention of declaring a many-to-many relationship between two objects by use of the join table. Thus, an assignment can have many groups, and groups can also have many assignments if a group persists throughout the course. A caveat though is to make sure that the join table is in alphabetical order, meaning it must be assignments_groups and not groups_assignments. That’s just the “convention-over-configuration” mantra of Rails at work.

Once we have the database schema set, we can then just go in and declare those relationships in the ActiveRecord classes respectively:


class Group < ActiveRecord::Base
has_and belongs_to_many :assignments
end
class Assignment < ActiveRecord::Base
has_and belongs_to_many :groups
end

However it is a different case if the join table contains extra information, which is our case with the memberships table. Here, not only does it reference the user and the group together, but it also contains extra information such as status of the member. Thus, we need to have a Membership class representing a member, and use has-many-through relationship. which sort of explicitly states that the association between a User and a Group uses memberships as its link. Here we declare the relationship as follows:

class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :members, :through => :memberships, :source => :user
end

Abstraction

We’ve also separated the old submissions table to a submissions and submission_files tables. The new submissions table doesn’t seem to have much information and seems to be a waste of space. However, having this table allows us to delegate submission functions to a Submissions class rather than mixing them directly with either the User or Group classes. All we have to do now is just ask a User or Group for its Submission instance, and handle all queries related to submitted files from it.

Since we also want to avoid checking to see if it is a User or a Group submission everytime, we’ve abstracted the Submissions class and added separate classes for each type, UserSubmission and GroupSubmission – classes that are linked to Users and Groups respectively. Since instead of declaring the relationship with Submissions, we have:

class User < ActiveRecord::Base
has_many :submissions, :classname => UserSubmission
end
class Group < ActiveRecord::Base
has_many :submissions, :classname => GroupSubmission
end

class UserSubmission < Submission
has_many :users
end
class Group
Submission < Submission
has_many :groups
end

This allows us to call either user.submissions or group.submissions and return with an instance of the appropriate Submission subclass type.

Final Results

The refactored models with the appropriate associations gave way to a much cleaner code in the end. With the schema set in place, I’ve revisited the old code and heeded the advice in the first post, stuffing all the business logic in the appropriate models and leaving workflow control to the controllers. The result turned several functions with 200+ lines into a single function with less than 50 lines. I was also able to create more thorough unit testing while code was being written. Here, we can see that we’ve improved our stats quite a bit:

$ for f in app/controllers app/models app/helpers; do echo $f
`find $f -name "*.rb" |xargs wc -l |tail -n1`; done
app/controllers 563
app/models 591
app/helpers 60

In retrospect, I think the refactoring decisions suits us very well with what we have in mind and gives us room for modifications at the same time…until we actually start porting OLM. Stay tuned.

Written by Geofrey

October 14th, 2008 at 6:32 pm

Migrate Your Tests

without comments

Rails has a nice way of maintaining versions of your database schema through ActiveRecord:Migration.  This lets you modify your existing schema without the hassle of manually copying the same schema to all the different deployed instances that you have, and does this automatically for you.

When I usually change the schema, I usually drop all the tables and recreate them using:

rake db:migrate VERSION=0
rake db:migrate

and then repopulate my development DB environment using a script I use.  However it turns out that this doesn’t migrate your test environment automatically with it. I tried creating a simple test of making sure that my ActiveRecord validation works.  However, I ended up getting this error:

test_numericality_group_limit(AssignmentTest):
NoMethodError: undefined method `group_limit=' for #<Assignment:0xb7242018>
/var/lib/gems/1.8/gems/activerecord-2.1.0/lib/active_record/attribute_methods.rb:251:in `method_missing'
test/unit/assignment_test.rb:11:in `test_numericality_group_limit'
/var/lib/gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:33:in `__send__'
/var/lib/gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:33:in `run'

After hours of finding the bug, I found out that you have to migrate your test DB environment as well, by executing the following:

rake db:schema:dump
rake db:test:prepare

This will copy the schema that you have right now in your development environment, and copy it to your test environment.

Written by Geofrey

August 6th, 2008 at 10:49 am