Tommy Lee Software development for everyone else

Cooking and Coding Together

Cook and Code 1

So Jimmy Vo and I have a time management problem. We try our best to balance what time we have to:

  • Expand and maintain our social circle
  • Learn new tech stuff or work on side projects
  • Cook and learn more recipes

So he came up with this brilliant idea: A meetup dedicated to cook and code.

Introducing Orlando’s Cook and Code Together

The concept is simple. Developers meet up. We prep some food together, then code. While the food is either marinating or cooking, we work on some personal development, with fellow developers nearby to bounce ideas or get assistance.

Meeting #1: Beef Burgundy

We chose a simple recipe, that takes a while to cook. I grew up eating my dad’s beef burgundy. Sweet, rich, meaty stew that takes an entire day to cook.

We found a recipe that can be cooked within 3 hours. You can find it here:

Beef burgundy recipe

Cook and Code Raw Ingredients

We divided the labor so that everyone can get to cook asap. I chopped up the vegetables, while Jimmy browned the steak chunks. Browning the meat is important in stews, since it adds additional flavor, and preserves some of the texture.

Cook and Code Raw Ingredients

So we threw in all the vegetables, with the water and bottle of wine into a large pot, and left it to cook. I made sure that it didn’t boil over and stirred it around occasionally.

Cook and Code Raw Ingredients

Coding Goals

For our coding session, we made goals that can be achieved by the end of the session. I try to use [S.M.A.R.T] goals as a framework of choosing what to complete.

For Jimmy, he’s playing with Azure and working on hosting his website.

For me, I’m playing with React to create a form page for one of my side projects.

As with any learning experience, we ran into some issues. I ran into some issues with the ES6 Syntax and how CommonJS module loading works. Jimmy’s azure account was having issues, and couldn’t get access to the right areas for deployment.

Around the hour mark, I check on the stew.

Cook and Code Raw Ingredients

We decided to work on figuring out how to get Jimmy’s project deployed. I remembered that .NET Core could be deployed on Ubuntu, so we went ahead and worked on some basic deployment on Ubuntu.

It was a great learning experience for Jimmy, since he’s from a Windows shop. It was some configurations of nginx, and installing .NET Core CLI to the server.

Cook and Code Raw Ingredients

We pick up a lot of small, unwritten things when we work with others. We learn habits from our friends and family, lessons from our mistakes. I passed down some of my experience doing sysadmin stuff, and deploying stuff on Linux. We learned from repeated errors trying to get the site to run.

In cooking, I made a great mistake with the initial prep for the stew. Instead of seeing the meat slowly get softer, but remain in one piece, the meat started breaking apart. The sweet, winey liquid I expected was non-existent.

I forgot to coat the meat in flour.

So we had braised beef instead.

Cook and Code Raw Ingredients

Lessons Learned for a Successful Cook and Code

So with a completed work, and a full stomach, we call the inaugural Cook and Code Together a success! We learned some new recipes to serve and food prep, and expanded what we knew and had something to work towards in the future.

Some recommendations we have for others:

  • Choose a recipe you haven’t tried yet
  • Divide the labor
  • Set measurable goals

Cook and Code Schedule Template

We follow the following time-line for most cook and codes.

  • 11:00 AM - Event Start and meal prep and cook. Social time and people get together.
  • 11:30 AM - Start coding. Waiting until the food is ready.
  • 02:00 PM - Food is served.
  • 03:00 PM - Clean up.

We have another cook and code coming up soon. We usually keep it small so that the group can work together well. While we can divide up the cooking for just one person, working together on the recipe lets everyone share in the experience.

Fixing Hot Reloads on Vagrant

One of the common issues that I’ve run into virtualizing my development environments is having to restart my server manually.

Whenever I developed locally, everything was fast, and changes appeared on first refresh. But when I used a VM, the frustration of restarting the server killed a lot of my productivity.

The Issue

Many of the hot reloads rely on detecting when the file has changed in your directory. Usually, we have something that watches the directory, and listens for a change.

Whenever a file is changed, the system kernel emits a notification letting a program know that something changed. In Linux systems, we have inotify, on OSX, it’s fsevents.

Since we’re using a virtual machine, our program is only listening to notifications emitted on the virtual machine.

Solution 1: Forward File Change Events

A recommended solution is to add a vagrant plugin to take care of forwarding file events to the VM.

Currently we’re using vagrant-fsnotify to forward events.

After installing the plugin we.

  1. add the fsnotify:true to our synced file directory.

    config.vm.synced_folder ".", "/vagrant", fsnotify: true
  2. Restart the machine

  3. Start vagrant fsnotify in a separate tab.

    vagrant fsnotify

Solution 2: Polling

An older recommendation is to switch to polling, which detects changes to the modification date occasionally. This was Ruby on Rails’ default detection method until version 4.

This is a fallback in cases where file event updates aren’t available. You can check your dev-server’s start system options, and see if a polling option exists.

I don’t recommend this, since polling takes up more memory and CPU, but if inotify forwarding is unavailable:

In this stackoverflow post, they enabled polling via vagrant rsync-auto.

Sorting between multiple Models in Ruby on Rails

Recently, I ran into a situation where I had two different Models where I needed to display both types of records in chronological order. We could grab all the records, and apply a simple sort.

  comments =
  posts =

  # Combine them together and sort.
  comments_and_posts = comments + posts
  comments_and_posts.sort! { |a, b| a.created_at <=> b.created_at }

  # Use Kaminari to paginate across
  results = Kaminari.paginate(comments_and_posts).page(params[:page])

While this is easy to read and understand, this is problematic as Comments and Posts grows. This method would require grabbing all the records before applying a sorted order. Pagination is also affected poorly, since we still need to grab both entire sets of records.

We can leverage the database to handle the sorting for us, but Rails does not have a pretty ORM way in the documentation to perform this kind of operation. We can use plain SQL.

Raw SQL Union

We use the UNION operator in SQL to combine both records together, then select from a subquery.

Since there is a possibility that ids are shared between the models, we need to generate a unique_id in these queries.

SELECT id, group_type, unique_id, created_at
  SELECT id,
        'comments' group_type,
        CONCAT('comments', id) as unique_id,
  FROM comments
  WHERE active = 1


  SELECT id,
         'posts' group_type,
         CONCAT('posts', id) as unique_id,
  FROM posts
  WHERE active = 1
) as results

ORDER BY created_at desc

We can add a LIMIT and OFFSET to use as pagination. Using a raw SQL query, we can pull out the information easily.

@connection = ActiveRecord::Base.connection
result = @connection.exec_query(sql_query)
comments_and_posts = []

result.each do |row|
  comments_and_posts << row

While we can go through each row in comments and posts and find by ID, that would give us about 25 additional queries. We can do a little extra work to reduce the amount of queries down to 2.

# Store their order in the array.
id_positions = { |x| x['unique_id'] }

items = comments_and_posts.group_by { |x| x['group_type'] }
items.each do |group_type, item|

  # Get only the ids to reduce amount of queries needed
  ids = item.collect { |x| x['id'] }

  if group_type == 'posts'
    content_items = Post.where(id: ids).to_ary
  elif group_type == 'comments'
    content_items = Comment.where(id: ids).to_ary

  # Replace original search with new searched content
  content_items.each do |content|
    unique_id = group_type +
    content_index = id_positions.index(unique_id)
    comments_and_posts[content_index] = content


Drawbacks to Raw SQL

By diving into Raw SQL, we have direct control of what to query. For smaller queries, this is manageable.

We lose some key features, like scopes. Scopes are composable, and simplifies our understanding of queries. We would have to maintain a separate set of queries if we decide to add filtering.

Raw SQL is also reliant on having a specific flavor of SQL. If we decide to switch MySQL to Postgres, some queries would change and break.

Using Arel to access existing scopes

We’re looking to use ActiveRecord’s Arel, to improve our codebases readability. Note: Since this is a private API, it may change without warning. It is expected that Arel becomes part of public API in Rails 5.1.

We can replace the raw SQL using Arel as a Query Builder. For ActiveRecord::Relation query, we can call .arel to drop into Arel.

Rewriting SQL into Arel Components

Since Arel is used to build queries only, we’ll end up transforming the resulting query builder to a SQL String with .to_sql.

So we’re going to create each part of our query piece by piece.

comments_query =
# Strip all the SELECT choices
comments_query.projections = []

# Select our items that we need
comments_query.projections(' as id',
                    'CONCAT("comments", as unique_id',
                    '"comments" as group_type')

# comments_query.to_sql generates

#   id,
#   'comments' group_type,
#   CONCAT('comments', id) as unique_id,
#   created_at
# FROM comments
# WHERE active = 1

posts_query =
posts_query.projections = []
posts_query.projections(' as id',
                  'CONCAT("posts", as unique_id',
                  '"posts" as group_type')

# post_query.to_sql generates

#   id,
#   'posts' group_type,
#   CONCAT('posts', id) as unique_id,
#   created_at
# FROM posts
# WHERE active = 1

We can then combine both of the queries together with a UNION.

combined_query = comments_query.union(:all, posts_query)

# (#{comments_query} UNION #{posts_query})

query =, Arel.sql("#{combined_query.to_sql} as results"))

# (#{comments_query} UNION #{posts_query}) as results

Calling, sql_string) gives us the equivalent of wrapping up combined_query into a subquery.

limit = 25
offset = 0
sql = query.project(
           .order("created_at DESC")

# SELECT * FROM (#{comments_query} UNION #{posts_query}) as results
# ORDER BY created_at DESC
# LIMIT 25

results = ActiveRecord::Base.connection.select_all(sql)

Standardized Front-end Tools to Increase Productivity

One of the challenges I ran into while learning modern front-end developments and frameworks is the challenge of putting all the ideas together. While I have a few years doing back-end development, and server side languages, my experience with client-side, Javascript, and SPAs was limited.

Learning difficulties

When I played with Angular, React or Meteor back in 2014-2015, I had a lot of questions. Some involved the tooling, but many were based in how to setup a project.

  • How do I structure a project?
  • What are the recommended best practices?
  • How do I deploy?
  • How do I handle testing?
  • How do I manage importing libraries and other packages?

Lost in the forest

These Modern frameworks required a lot more planning, thought and research for me to get running. Having to development my own project structure, or having a few restructures, was frustrating.

I had a little assistance from a local Javascript Expert Chris McClean, and having fellow developers would help out in the learning process. This would be easier though for everyone if there was a simplified process in setting up and getting ready to go.

Starter Packs and Generators

One of the ways we used to start projects was using existing starter packs, or Yeoman. This gave us a better experience in generating an existing project, and allowed us to get up and get going.

Set it up for me

Having a default preference set up allows us to move onto the more important areas of our app. Starters usually fix issues like:

  • ES6 Transpiling
  • Minification and Compilation
  • Generating a Production Target
  • Wiring up the folders

Starter packs

While this made it a lot easier to build out projects, it had some issues. Some starters that exist are specific to a certain configuration. I used an older Yeoman starter for Angular, which used less recent build tools like Bower and Grunt.

It was also structured in an MVC project structure, while the community recommends a Feature based project structure.

  • Relied on the generator’s documentation
  • Could use older, not current best practices
  • Hard to debug if you don’t know what the different tools are doing.

We love Official Command Line Tools

It’s increasingly common for many web developers to use some form of command line tools to better improve productivity. In the Javascript world, it’s almost required to use npm to manage packages.

Recently, the major Javascript Frameworks have released their cli version of the tool to help create new projects, components, and build and serve. These were based on ember-cli, and allow us to start working and not worry about all the other intricacies.

I’ve been playing with Angular 2’s ng-cli, and I feel it improves my qualify of life for development. Other than generating default code, it allows for the following:

  • Well defined conventions
  • Easier support
  • keeps my mental overhead small

Conventions reduces conflict

While people argue about different kinds of conventions, many will agree that conventions are a good thing. By having a defined set of conventions for a project, people would generally know where to put things.

When the documentation is not a best practice

One of the issues I ran into while learning Angular 1 came from a lack of agreed upon conventions. While the official documentation showed one way to create directives, the community documentation and best practices recommended a separate way.

Have defaults cover most common use-case

Angular 2 took recommendations and practices from the community and have built tools that support the best practice. The issue of how you should set up your Components or Services is already made up. Calling ng generate component my-component-name creates all the steps you need.

Easier support

One of the benefits of having a standard structure in an application is easier ways to support the application later.

Problems are Google-able

When we have to create our own structure while we’re learning, lots of minor breakage and mysterious problems occasionally appear. We try to google issues, and many of the cases found are almost close to ours, but don’t work.

When standards exist, we have an understanding of what should happen, and it makes it easier to communicate.

Easier to onboard new developers

Newer people have an easier time looking up documentation, and can use the built-in tools to do accomplish tasks better. When we work on a project that has lower documentation, or using a bespoke framework, it can be difficult to comprehend what is exactly going on.

I can focus on the big things.

There are times where I feel like I’ve written the same set of code over and over again. Looked up similar documentation each time, because it was not obvious on how I should structure an area.

Standard Tools allow me to not think, and have it be easily available to do some things.

Finishing your blog posts

I have about 10-15 half-finished ideas and blog posts. Each of these ideas take off in full force! Full of passion and enthusiasm, the words and ideas come easily.

Then, somewhere around the first few hours, I lose focus on the goals of the article.

The following is a small set of ideas and strategies that I use to cope with completing blog posts, and any project.

1. Prioritize Completion

We say we’ll do it on our free time, but that free time will always be filled.

We need to make finishing these blog posts and ideas a higher priority. I remember Stephen Covey’s Quadrants for Time Management as a way to decide what’s important.

Aim for Important and Not Urgent

We should categorize items like blog post Not Urgent and Important. These should be highest priority.

Set a Goal

Goals and deadlines can give us focus on what we can accomplish in a timely manner.

When we don’t have goals or deadlines, ideas such as this will be put on the back-burner.

I aim for 1 blog post a month as a goal.

2. Write for a Single Person

Think of certain person in mind when we write a post. This person who could definitely find our article useful, informational or entertaining.

Having an audience in mind reminds us on who is waiting for the article, and the kind of information to include. We can tailor our writing to this person.

This may not accommodate everyone, but that’s okay. Let’s aim for effectiveness, rather than appeal.

Technical Articles

Technical articles are usually difficult for me to pin down.

One part is trying to justify that I know the subject. So I:

  • Write in great detail
  • Argue and illustrate the subtleties
  • Get really dry on the topic

Another Part of me is writing in a way to avoid arguments, leading to a lot of:

  • Cross chatter
  • Self Arguing
  • Showing too many sides of the argument

While I enjoy expounding all these details, and being well educated on the topic, too often, I forget who is actually reading.

For tutorials, I illustrate my way as ‘a way’ to accomplish the task, with links to references or other people’s tutorials.

For more subjective writings, I try to present the other side fair enough.

3. Overwhelmed? Rambling? Reduce Scope

When we create stuff, sometimes we want to go very deep into the nitty gritty, and talk about the finer details, and subtleties.

Now to write or finish a blog post, we have to first create the universe.

Then we have an outline that is longer than anyone wants to read.

What to cut

We should only cut down our scope if it starts being unmanageable.

We focus each section down to one purpose. Maybe the entire blog post idea should be reduced down to one idea.

4. Dedicate some time!

Currently this is about the third or fourth writing session at completing this article. I try to squeeze in these blogs on my downtime, but I love not having downtime.

One of my favorite things about free-time is that I spend a lot of that time deciding what to do with the precious time.

Part of the Schedule

The lack of scheduling, and the freedom to do anything results in a whole lot of nothing.

I work on scheduling my free-time in a more rigid schedule. After work and dinner, I have a few hours to spend.

Each week, I schedule about an hour or two for the blogging and writing, and no more. Any more time spent might lead to increased distractions and slacking off for me.

No Confidence? Scared of Completing?

We worry too much about the opinions of others and their negative attitudes. We let the invisible hating peanut gallery crawl into our brain, and shake up our attempts at anything.

Then we sit around, with nothing on the screen, paralyzed by the fear of our own inadequacies. We feel that we’re not good enough, that everyone will rip us to shreds, and the best course of action is to do nothing.

Then the existential dread kicks in, and life spirals out of control, due to us trying to write a blog article.

Well, probably. That might happen.

An Optimistic Approach

Being frightened is okay. It’s something that never really goes away, but we sort of get used to the feeling of being uncomfortable. Like learning a new language, trying something new on, the natural anxiousness that arises, that’s normal.

Hey, you’re doing it. That’s a lot more to say than a lot of others. You gave yourself a challenge, and you’re fighting your way through it. That’s awesome. Look how far you came, this was a blank space before.

For me, I can have a fully rendered page and say ‘Hey I made this!’ That’s really the prize is the completion of the long road ahead.

There will be people out there that haven’t heard of your information, and will look to your piece of information as useful. It may not be until a very long time from now, but that possibility exists.

Your work will be there for someone’s One in 10,000.

A Pessimist Approach

We may have put our work too high on the pedestal. We’re so concerned about the criticism, we forget about being realistic. There’s so much content out there, what will guarantee that people read it? Most people will give it a passing glance. At least someone’s reading.

When was the last time you felt so impassioned over an internet article or blog post that you wrote a scathing tirade, attacking everything about the person? Well, most people don’t have really strong opinions about it. 90% of people just read it and move on.

The angry critics reflect more on themselves then your actual writing. This blog post on online harrassment reached out to me on understanding the issues I run into with comments online.

For me, I know that the only people who are going to read this blog post are those that I share it with, and maybe a few bot scrapes.

Whatever Keeps you writing

The important thing to take away is to do whatever you need to get these projects complete.