Attending Globalhack VI

A couple co workers and myself registered for this hackathon to end homelessness in the St. Louis region. We are currently awaiting the true challenge of the hackathon. I will update this post more throughout the weekend.

Update (11/2/2016)

So the hackathon is over. We didn’t win any prizes but learned several things about out team and pieces of our development process we can improve. We mainly use Ruby on Rails (Rails) as our development environment, some of the things we learned pertained to that style of development.

First, thing we learned is using generators is great, but I like my code formatted a certain way, different than the scaffold generators, generate code. This would mean we need to create our own set to use to quickly build an application. I have started a open source project for these generators, because I use Rails outside of work as well.

Second, I learned how uncomfortable I get writing code without any unit tests. I have come to believe that they are necessary, they help with not having to manually test multiple pieces of code continually. We chose not to use tests, we had parts of our app that didn’t work properly. Not sure how to feel here, I understand they take time and when you have less than 48 hours to develop a functioning app stuff gets cut. I am looking forward to build some generators, because it should help by pre generating those tests for us.

Overall it was a fun experience for my first hackathon and learned quite a bit about myself, my development skills, and my development style. I look forward to taking what I learned and improving myself over the next several months.

Resetting Rails Counter Cache with ActiveJob

I have recently tried something a little different, when working with Rails counter caches. For those new to rails counter cache columns are where you setup a column to hold a count of a has_many relationship to make a lookup faster than a count SQL query. You can read more about that more about them in the API, Rails Associations

I tried setting up resetting counter caches in ActiveJob, instead of using a rake task to do so. Use case for this would be when someone updates the count from SQL or when you first implement the counts. This would allow me to call the job from the admin interface of my application, I still can call the job from a rake task if I needed to. Lets take a closer look:

I started thinking how to do this efficiently without minimal coding. I started digging to see how to turn snake case into a class name, so I take something like category and turn it into Category. I know the generators that come baked into Rails work this way, so I searched the Rails repository on github, to see how it works and used it in this example.

The update script uses a JSON file to store the class and the relating relationships that need updated. It is structured with the class name in snake case as the key, and the value of an array of all the relationships needing updated. See the example below.

Now for the job code (see below). The job accepts one parameter which is the key. The key is the key from the JSON file discussed earlier so you can do all tables or just a single table, to allow for maximum flexibility, or concurrency since we are using Active Job. To use concurrency simple spin each class in its own job. The job loads the JSON file storing the configuration, and depending on if a key was passed it will loop through all keys and columns or just the one specified.

For the actual business end of things the update_cache_columns method does the brunt of the work. The method takes the key and turns it into a class_name, and updates each one of it’s cache columns.

Testing this is easy. First, we’ll create the related object and update the count via raw SQL. Then we’ll finally run the job and verify it updated the count successfully.

I am including my base model code, to help any one see how a counter cache is setup. The category relation on ArticleCategory contains counter_cache: :articles_count, which is what typically updates the column in the category table every time one is created or destroyed. The job above is for when the counts are wrong due to something going a rye.

This is a different spin on how this is typically handled. I welcome any thoughts on this implementation.