I had a relatively simple task. I wanted to display a calendar with a sidebar that showed upcoming items (what these items are is a bit more detailed but not important here).
I wanted the sidebar to show 10 items to start with and let the user load another 10 by clicking a button.
One key peice was that I wanted the items to be ordered by month with a header every time a new month started.
The last part was a time-suck but in the end turned out well.
What I Spent Time Trying
I knew I would use the following:
- Rails (this is a feature for an existing project)
- AJAX to load in the 10 new items at a time
- Altered pagination to get 10 items at a time (already using the pagination gem so the overhead was already there so I figured I might as well use it again for this)
And then how to order items and show a month heading when loading 10 results at a time that could span any number of months (up to 10 I guess). Below was my desired output.
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
- Item 7
- Item 8
- Item 9
- Item 10
Load More Button
If Item 11 is in month 3 it should be added to the month 3 list without a new heading. If it’s a new month, it should get a heading and be added to the list.
I could easily figure out how to return a group of items with a month header or how to return 10 items at a time in order either with Ruby and/or sql. But I couldn’t figure out how to return 10 items and only add a new heading at the start of a new month.
I could use sql to group or order the results. I could get all the results and use Ruby’s
group_by method. But once I thought about returning the results to the front-end I ran into troubles.
What I Ended Up Doing
I realized I was thinking about the front-end result and trying to get my back-end to structure my data based on a UI design I had in mind. Not clean seperation of responsibilities.
I thought about if I was building a service or writing an Angular app consuming a service I would likely get a list of items, specify the order, and possible the number of records. After that it would be up to the front-end to decide how to handle it and display it.
From that I decided to add a
data-month attribute to my items when I was building them out on the front-end.
data-month attribute I could use css to insert the month before items each time a new month appears. I wish the css was a bit cleaner/less repetative but for now it works well for now.
And my back-end can easily return ordered results 10 at a time. No grouping or sorting to worry about.
Wrap it up
I sometimes spend a lot of time trying to figure out the best way to do something (how can I do it all at once, the most effecient way, etc). Here I realized I need to take a step back and keep it simple.
- Keep responsibilities seperate
- Don’t be affraid to get it working and then refactor
- Let each thing do what it’s good at