For the past while, I’ve been working on updating the database schema for the relationship between Submissions and Results. Originally, Submissions was created so it had a one to one relationship with Results. However, a feature was later added so that students could submit remark requests, requiring more than one result to be related to a single submission. The schema was then changed so that submissions had the following relation:
has_one :result, :dependent => :destroy
belongs_to :remark_result, :class_name => “Result”
Where ideally, we would want a has_many relationship. With the previous implementation, an error appeared about old results sometimes not showing up (documented in this blog post). A quick fix was implemented but it was dependent on database ordering and time stamps. I took the following steps to improve this implementation and schema:
1. The schema
– I updated removed the belongs_to remark_result relation, and changed the has_one result to has_many
– This change means that submission.results will return an array of results and that we can no longer call submission.result and submission.remark_result to get the results
2. Helper methods
– I implemented two helper methods: get_original_result and get_remark_result that would return the appropriate result for the submission
– These helper methods utilized the already existing field: remark_result_id in the Submissions table in order to differentiate between the two results (this removed our dependency on ordering/timestamps)
3. Updating the code base
– I updated the way results were created so that they would add to the array of results, and I had to manually fill in the remark_result_id column of the Submissions table when a remark result is created (since the belongs_to dependency no longer exists)
– All areas of the code that were using either the result or remark_result had to be updated with the helper methods and then tested to ensure functionality did not change
Originally, the suggestion on issue-941 (the schema update issue) was for the two methods to be get_result and get_old_result. The idea behind the methods was that get_result would return the remark result, if it exists, otherwise return the original result. Then, get_old_result, if a remark result exists, would return the original. When I implemented this approach, I realized several errors and differing functionality. Comparing it to the original code, I realized that the remark result was actually not being used in many places in the code base and that the original was result was generally used most of the time (without checking if a remark exists). Another problem is that in some cases you only want the latest completed result to be displayed rather than just the latest existing result.
So, the approach we took was to update the schema without changing any functionality (by using helper methods that would return the same type of result – original or remark – each time), and then follow up by going over sections of the code and updating them so that they will be using the appropriate result in that case. This issue has been opened and can be found here.
My suggestion for implementation is to create another helper method, get_latest_result, that would utilize the current helper methods get_original_result, get_remark_result, has_remark?, and remark_submitted? to return the latest result (note: only use remark result if remark request has been submitted). We would have to determine areas where this method would be appropriate to use instead of always using the original result.
As per the “Next Steps” section, I have added in helper methods and then gone over the code base that uses results, updating method calls where appropriate. I implemented two helper methods: get_latest_result and get_latest_completed_result for the update. The former will return a remark result only if the remark request has been submitted, and the latter will only return a result whose marking state is “completed”. These changes can be found in pull-request 1058.