Performant Queries with ActiveRecord Includes

Let’s say we have a User model and each user has many Posts. To get a list of all of the posts for a user we may do something like:

posts = User.all.map { |u| u.posts }

This is perfectly reasonable and will work for a majority of cases. However, if you have a large number of users and posts this can be a very slow lookup. This line of code will run N + 1 queries. The first SQL query will be to retrieve a list of all users and then execute N SQL queries to retrieve the posts for each user.

The includes method allows you to specify relationships to be included in the resulting set of data. This is often called eager loading and improves performance because it allows you to retrieve all the data you need in a single query, without firing additional queries.

users_with_posts = User.includes(:posts)

Debug Vim Configs with Verbose

Have you ever added a new command or option to your .vimrc and not see the changes reflected?

The reason might be that the option is being overriden by another plugin. The verbose command in Vim shows you what the current value is as well as where it is being defined.

:verbose set conceallevel

This outputs:

conceallevel=0
Last set from ~/.vim/plugged/vim-devicons/plugin/webdevicons.vim line 326

Git Log Tree View

The git log command shows the commit log history. The command below draws a graphical tree representation of the commit history:

git log --graph --decorate --oneline

Git Tree Log

To make it easier you can alias the command:

alias gl="git log --graph --decorate --oneline"

Navigate to URL using Vim

Vim makes it easy to open a URL in your browser while navigating a file.

Put the cursor over a URL in normal mode. Then type gx.

Dynamic Finders in Rails

Ruby on Rails makes it easy to find a specific record in a table based off some fields. With Active Record you can search a model easily by the following:

User.find_by(first_name: 'Sunny', last_name: 'Mistry')

A cool feature that Rails provides is dynamically generating finder methods for every field on a table.

User.find_by_first_name('Sunny')

An even crazier thing is you can do this for multiple fields!

User.find_by_first_name_and_last_name('Sunny', 'Mistry')

This can go on for as many attributes as you like. I’m not really sure why anyone would do this but it is interesting.

Dynamic Finders Rails Guides

Source Code and Implementation

Custom Search Engines in Chrome

Custom Search Engine Example

Every day I go to websites where the URLs are the same except for one part of the path. For example GitHub repositories are under structured URLs like https://github.com/sunnymis/project1 and https://github.com/sunnymis/project2. Jira tickets are under URLs like https://company.atlassian.net/browse/PROJ-100 and https://company.atlassian.net/browse/PROJ-123. To make it easier to jump directly to a certain page you can leverage custom search engines in Google Chrome. Custom search engines enable you to type some characters, hit tab, and then characters to enter into your URL.

Steps:

  1. Right click the URL bar
  2. Click Edit Search Engines…
  3. Next to Other search engines click Add
  4. Enter a name under Search engine
  5. Keyword is important. This is a shortcut you can type in your browser which will trigger the custom engine. For GitHub you can use gh. For a Jira project named PROJ you can make the keyword proj.
  6. In the URL field enter the URL but add %s wherever you want to put your query. For example: https://github.com/sunnymis/%s

Thats it! Now you can type gh, enter the tab key, and type your github repo name and you’ll be navigated there.

Big Query EXCEPT

When querying relational tables in Big Query you might want to grab all the columns except a couple. I’ve run into this a few times where I want all the data from two joined tables, but I don’t want the created_at, updated_at columns that they both contain. Big Query will throw an error saying you can’t have duplicate columns. This can be fixed using EXCEPT

SELECT A.*, B.* EXCEPT (created_at, updated_at)
FROM A
LEFT JOIN B
ON a.id = b.a_id

Big Query SQL Query Syntax Reference

Element.scrollIntoView()

scrollIntoView() is a function that exists on Document Elements. It provides the ability to scroll to the provided element’s parent container.

let elem = document.getElementById('title');

elem.scrollIntoView();

It takes in a few optional parameters that you can use to configure the scroll alignment and transition.

elem.scrollIntoView({ behavior: 'smooth' });

MDN Reference

Array.prototype.unshift()

The unshift method on JavaScript arrays lets you append items to the beginning of the list.

Let’s say you are creating a dropdown list of items but the first item in the list should be a placeholder value to show the user before they select an actual value.

const renderOptions = () => {
  const dropdownOptions = [
    { label: 'Apple', value: 'apple' },
    { label: 'Banana', value: 'banana' },
    { label: 'Cherry', value: 'cherry' }
  ];

  dropdownOptions.unshift({ label: 'Select a fruit', value: '' });

  return dropdownOptions;
}

This renders the following array:

[
  { label: 'Select a fruit', value: '' },
  { label: 'Apple', value: 'apple' },
  { label: 'Banana', value: 'banana' },
  { label: 'Cherry', value: 'cherry' },
]

This is a short way to add items to the beginning of an array. However, I don’t prefer to use this method because the method unshift doesn’t immediately tell me what’s happening if I have never come across it before. I prefer to write code that is more readable. For example:

const renderOptions = () => {
  const dropdownOptions = [
    { label: 'Apple', value: 'apple' },
    { label: 'Banana', value: 'banana' },
    { label: 'Cherry', value: 'cherry' }
  ];

  const placeholderOption = { label: 'Select a fruit', value: '' };

  return [placeholderOption, ...dropdownOptions];
}

Using the spread operator I can easily return an array that puts the placeholder option first followed by the rest of the list. The code is much easier to reason about now.

Chrome Tab Shortcuts as a Standalone App

Google Chrome lets you create shortcuts from your tabs that function similarly to desktop apps.

Click the triple dot menu icon -> More Tools -> Create Shortcut... -> Open as window -> OK

Now your tab can be viewed as a separate app. In the image below I have Hacker News, Jira, Google Calendar, Gmail and even this site as apps.

Chrome Shortcuts Example

All apps that are created can be viewed by navigating to chrome://apps/

Remove Tracked Files From Git

This has happened to me multiple times, especially with the dreaded .DS_Store file. I’ll stage all of the files that have changed (git add .) and, without noticing, also add in the .DS_Store. Adding this file to .gitignore will still cause it to be tracked because git cached it. You can stop these kinds of files from being tracked with the following command:

git rm --cached <file>

Increase Mac Keyboard Speed

First, check what your current keyboard repeat rates are with the following two commands. These values can be used to revert any changes you make.

defaults read -g KeyRepeat

defaults read -g InitialKeyRepeat

The below two commands update the default keyboard repeat rate to make it blazing fast

defaults write -g KeyRepeat -int 1

defaults write -g InitialKeyRepeat -int 15

Zero Delays

const zeroDelayExample = () => {
  console.log('This will come first');
  
  setTimeout(() => {
    console.log('Zero delay will come third');
  }, 0);

  console.log('This will come second');
}  

In the above example, a setTimeout doesn’t function the way it normally does. That is, it won’t execute after 0 milliseconds (or immediately).

The 0 parameter tells setTimeout to only execute after all of the messages in the event loop’s queue are finished.

In this case when zeroDelayExample gets called, the first console.log will be called, the setTimeout will wait for all other events to finish, then the third console.log will be called. Finally, the setTimeout callback gets fired.