Rebooting the Schema (part 1)
Starting off this project, we’ve decided to start fresh with our model schema. When I started with Rails, and my first time developing on an MVC framework, I’ve always wondered how to decide what goes in the model and what goes in the controllers. After our summer iteration, a Rails reviewer came in to see the status of the code. With a little bit of console magic, he showed us this:
$ for f in app/controllers app/models app/helpers; do echo $f
`find $f -name "*.rb" |xargs wc -l |tail -n1`; done
He suggested that we should try to put most of the controller functions in the models as much as possible. That way, we can do a more thorough and fine-grained unit testing without mixing data functions to the workflow that controllers are suppose to do. To answer my question, he gave this advice:
One way to force oneself to use models more:
controllers should only have the methods pertaining to RESTful resources.
That way, the controller’s job would only be tying up together the business logic through the models and use the models to share code between controllers. Andrew, one of the students working on the project, also suggested to make use of the ActiveRecord relationships rather than having customized SQL queries in the code.
Before refactoring, the DB schema looked like this:
There were a lot of redundancies with this schema. For example, the group table not only contains group information but also maintains a record for each member of a group. Thus, a group with four members would have four records in the group table containing the same group_number and assignment_id. Also, if the same group persisted throughout the assignments in the course, then we would have to duplicate those four records for each assignment.
The simplicity of the tables also made it hard to actually manage it on the models layer. With no join tables to work on, I was using functions to wrap hard-coded ActiveRecord queries.
In the next post, I’ll talk about what the new schema looks like and what improvements we’ve made in the code.