MarkUs Blog

MarkUs Developers Blog About Their Project

Preserving column order – GradeEntryForms

without comments

The problem: grade spreadsheet columns were being sorted by name instead of maintaining the order they were added in.

GradeEntryForm – new: creating columns for new spreadsheet

GradeEntryForm – grades: columns are now ordered by name

Knowing nothing about Ruby, this seemed like a simple task. Preserving rubric orders was already being done. It should just be a matter of saying ‘update the database in the same order you get it’, right?

Wrong. The controller receives the parameters to update the grade entry form as a hash, :params, which is unordered. So to update the database in the right order, we are going to have to decide in the view what the order should be so that it can be sent with the params.

But before working on that, maybe we can see how rubrics get their order. It turns out that rubrics get added to already created assignments (first difference) and that they are created one at a time (second difference). Their ordering is therefore much simpler because the parent is already in the database, and then it is just a matter of saving each one individually, making sure to fill in the required attributes (name and weight) before saving. This means you can just save each new rubric with a position that is either 1 more than the previous max position, or 0 if it is the first rubric for the assignment. Unfortunately, using this method for the grade entry forms would make their creation a lot more tedious than is necessary, so this idea was scrapped.

The biggest problem with adding positions through the view is that the link to add new columns is in javascript since spreadsheets don’t have to exist yet before adding columns. I couldn’t find a way of getting the javascript to update the positions every time the link was clicked. It seems that the javascript in link_to_function is evaluated just once when the page is loaded, and that initial result is used every time the function is called. I came to this conclusion because placing a puts statement inside the add_grade_entry_item_link in grade_entry_form_helper.rb results in a single printed line during the loading of the page and doesn’t print out if the link is clicked. Therefore, adding a position to new columns needs to be done in the controller after the call to submit but before saving.

The final solution was as follows:

  1. Create a migration that adds a new attribute ‘position’ to GradeEntryItems. Update GradeEntryForms to order their GradeEntryItems by position.

  2. The ‘add_grade_entry_item_link’ method in grade_entry_form_helper.rb is already setting the key of the new columns to be added as ‘new_####’ where #### is the timestamp. This is sent in the POST params to the grade_entry_form_controller.rb for the create and update methods.

  3. Create a new method ‘update_grade_entry_form_params’ in grade_entry_form_helper.rb that sorts by name all of the columns that don’t already have a position. This will put all the new columns in order because they are named by timestamp. Then based on the current highest position, it adds a position to all new columns.

  4. In grade_entry_form_controller.rb, create and update either successfully update the model with the new params or it fail because there was an error during validation. If an error occurs, the view reloads with the old columns in the proper order (because GradeEntryForm returns them sorted by position) but the new columns in random order. Therefore, create a new method ‘sort_items_by_position’ in grade_entry_form_helper.rb so that the view can display the forms for the items in the proper order.

  5. When displaying the current columns in the view, I also added that it updated each item’s position so that if any columns were deleted previously, the current ones would fill in the gaps left by them. This doesn’t ensure continuous positions completely, but the only gaps in position are now only from one round of deletions and not every round of deletions.

It was more complicated than it first seemed, but the final solution seems to work pretty well!

Written by Arianne Dee

December 10th, 2013 at 5:18 am

Posted in Uncategorized

Leave a Reply