ActiveRecord to JSON API Part 3: Handling Filtering

Did you know that Puma has a 10,240 character query string limit? We do now.

In the process of building our internal JSON API, we found two issues with handling filtering:

  1. Query string limitations
  2. Querying for an array of IDs when some values were nil

Background

We were building an internal JSON API using the following libraries:

For more information on our goals and set up for the internal API, see part 1 of this series.

Query Strings

Given that the JsonApiClient filtering methods use an HTTP GET with query string parameters, character limits quickly became a concern for us. How could we ensure that some of our lengthier queries weren’t exceeding the limit and failing?

The simplest solution to us was to make the filters a POST request, even if that was a divergence

Continue reading “ActiveRecord to JSON API Part 3: Handling Filtering”

Write A Reduce Function From Scratch

JavaScript's Array object has a built-in reduce method. This is a handy,
yet underutilized method. Let's take a closer look at what reduce does and
see if we can implement it from scratch.

Reduce?

Here is what
MDN
has to say about reduce:

The reduce() method executes a reducer function (that you provide) on each
member of the array resulting in a single output value.

So, we can take an array of things and turn it into something else using a
function that we get to define.

const sum = list => list.reduce((total, val) => total + val, 0);

sum([1,2,3,4]) // => 10

The reduce method can seem pretty limiting at first when we read that it
produces "a single output value." That makes it sound like all it is good
for

Continue reading “Write A Reduce Function From Scratch”

ActiveRecord to JSON API Part 2: Solving Pagination

While building an internal JSON API for a Rails application, we came across a few issues with pagination.

  • Making Kaminari work
  • Resolving problems with pagination link parameters
  • Enabling pagination while still allowing users to get everything

Background

We were building an internal JSON API using the following libraries:

For more information on our goals and set up for the internal API, see part 1 of this series.

Kaminari

The application we were working on was using Kaminari for pagination, and one of the first things we noticed during our switch from ActiveRecord to JsonApiClient::Resources was that pagination no longer worked, but only when the page number param was not present.

Upon investigating the source code for JsonApiClient, we noticed that when the page number param was blank during pagination, the page was resolved to 0,

Continue reading “ActiveRecord to JSON API Part 2: Solving Pagination”

Use Yarn Like a Pro

Yarn is a fast, reliable, and secure alternative to NPM. In this post, we'll look at techniques to use Yarn to its fullest.

The expectations of life depend upon diligence; the mechanic that would
perfect his work must first sharpen his tools. —Confucius

Yarn is a great tool. I'm won't wade into the Yarn vs. NPM debate,
because the tradeoffs are always in flux. I just say that I've been
using it for two years on a variety of projects, and have nothing but praise.

Part of that journey has been learning Yarn's nuances, and today I'm happy to be
sharing them with you. Some of these epiphanies came to me through my own work,
and some via our company knowledge base, Today I
Learned
.

I'm going to skip the setup and some common Yarn commands; head over to Yarn's
official site
to boot up. All of these commands were

Continue reading “Use Yarn Like a Pro”

ActiveRecord to JSON API Part 1: Our Approach

In a recent Rails project, we were tasked with the migration of a group of ActiveRecord models to a microservice that had not yet been built.

This raised an interesting question for us: how do we migrate data out of an application when we don’t have anything to replace it with?

Reasoning

The originally proposed solution was to build a layer between the controllers and models that would delegate out to the ActiveRecord models for now, and then when the new microservice was done, would delegate out to an ActiveResource object. This solution raised some concerns for us.

  • How would we update the models and jobs that interacted with the models being extracted, when the layer was only present in the controllers?
  • How do we know the performance impact of moving from a database record to fetching data from an API?
  • How do we know we’ve properly converted everything when

    Continue reading “ActiveRecord to JSON API Part 1: Our Approach”

How To Quit Vim

A lot of people would have you believe that Vim is near impossible to quit.
I'm here to dispel the rumors and show that there are quite a few ways to
quit Vim.

The Basic Quit

First thing if you start up a new Vim session with just vim, you'll see a
sort of splash screen. Below the title and copyright information is this
line:

type  :q<Enter>               to exit

This is a good place to start because it is perhaps the most straightforward
way to quit a Vim session — the :q or :quit command. It does come with
some minor caveats.

Here is the first caveat. If the current file (or some other file open in
another buffer) has been edited, but not yet saved, then Vim will stop you
from quitting. It wants to make sure you don't accidentally lose your
changes.

If you're sure you want

Continue reading “How To Quit Vim”

Integrating with Google Calendar as a Service App

Recently, I was working on a project where the goal was to have a shared calendar for the application that all the users would have access to, but no individual user would have ownership of. This seemed like the perfect use case to have a service app owned calendar that gave access to users based on email addresses.

I started by going to the Google developers console, creating a new project, creating service app account credentials, and enabling the Google Calendar API.

I used two libraries for setting up the integration:

Basic App Set Up

I was working with users that had access to many calendars, and those calendars had many events.

class User < ApplicationRecord
  has_many :calendar_users
  has_many :calendars, through: :calendar_users
end

class Calendar < ApplicationRecord
  has_many :calendar_users
  has_many :users, through: :calendar_users
  has_many 
Continue reading "Integrating with Google Calendar as a Service App"

Generate Images for Instagram

Followers of Hashrocket on social media will note our renewed presence
on Instagram, punctuated by a collection of custom images. In this post, I
will try to reverse-engineer these images using ImageMagick.

Hashrocket project manager Suzanne Erin recently started creating a series of
engaging images for our Instagram account to pair with blog posts. An example:

handmade image

Soon, I started to wonder if I could reverse-engineer these
images with code. Here’s what I came up with:

generated image

In this post, I'll explain how I created this image.

Concept

I wanted a CLI accepting two arguments: a background image and a blog post
title. With no other interaction, it should return a finished image.

Part of what powers this idea are the folks at Unsplash, who provide wonderful free photographs. I'm a huge
fan of their service, and always try to give the appropriate credit. These images would work with stock photography,

Continue reading “Generate Images for Instagram”

Session Zero for Software Teams

I recently spoke at our Hashrocket Miniconf about a concept I learned from the tabletop role-playing game community: Session Zero.

Before I get into Session Zero, let’s set the stage. What is tabletop role-playing? Think Dungeons and Dragons. I know we’re all some flavor of nerd here on the internet, but if you’re not familiar with these types of games, here’s a simplified description: Generally a tabletop role-playing game (RPG) consists of participants who play characters with different attributes and abilities. Players describe their characters actions and roll dice to see whether they succeed. A campaign in an RPG is a series of challenges or situations that are presented to the players as they progress through a fictional setting. A Game Master (GM) sets the scenes, presents the challenges, and adjudicates the rules for the players. A campaign is a longer term game played out over a series of sessions.

Continue reading “Session Zero for Software Teams”

SQL: Inner Join vs. Outer Join

A standard join in SQL is implicitly an inner join. This means that only
records that can be matched on both sides of the join will be included in
the result set.

Here is an example of that:

> select * from table_a join table_b on table_a.letter = table_b.letter;
 name  | letter |  name  | letter
-------+--------+--------+--------
 Brian | A      | Dunn   | A
 Derek | C      | Parker | C

That same query could be written with inner join.

We can alternatively write an outer join which will ensure that the
subject of the join has all of it's rows included even if there isn't a
matching row from the other table.

So, which table is the subject of the join? If it is a left outer join,
then it is the table on the left of the join. If it is a right outer

Continue reading "SQL: Inner Join vs. Outer Join"

Friday Lunch at Hashrocket Chicago

Friday is a special day at Hashrocket.

Friday is our open source day. After spending the first half of the day working on regular client projects, Rocketeers spend the afternoon honing their skills by contributing to open source, working on side projects, brushing up on new languages, or working on company initiatives. The other very special part about Friday is lunch. We kick-off the open source afternoon by dining out together as a team. This is an important tradition, because we are divided across many separate project teams and there aren’t always as many opportunities for everyone to have a conversation together as we would like. This helps us stay connected to each other.

In Chicago our office is nearby the West Loop, known for its restaurants and cafes. This means that we have many delicious dining options. How to choose? If you’ve ever tried to get 9 people to

Continue reading “Friday Lunch at Hashrocket Chicago”

5 JavaScript Object Destructuring Tricks

The ES6 destructuring syntax is quite flexible. It allows us to do a lot of
nice things with objects and arrays that in the past would have taken many
distracting lines of code.

Let's look at five handy destructuring tricks for objects.

Trick #1

Remove an item from an object

// const data = { a: 1, b: 2, thingToRemove: "bye" };

const { thingToRemove, ...rest } = data;

console.log(rest); // { a: 1, b: 2 }

This is a concise way of getting a new copy of an object with a specific
key/value pair removed. Note that it is immutable and you are free to
specify as many keys as you'd like separated from the ...rest object.

Trick #2

Rename things in a destructuring

// const data = { coordinates: { x: 5, y: 6 }};

const { x: xCoord, y
Continue reading "5 JavaScript Object Destructuring Tricks"

Today I Learned 2018: Year In Review

Today I Learned is an open-source Elixir Phoenix project by Hashrocket. One of the fun things about January is being inspired to look back at the past year. This blog revisits some of the top trends and posts in Today I Learned of 2018.

In 2018, we at Hashrocket posted 379 TILs. On average, we collectively were learning something new every day!

Our top-two most popular posts of the year were both #elixir posts:

The three topics that we posted TILs about most often were:

  1. #javascript (56 posts)
  2. #react (52 posts)
  3. #reasonml (44 posts)

A huge portion of our work this year involved React and JavaScript so it is no surprise that we were learning a lot in those areas! Here are the top posts from each of those categories:

Managing React Router Pathnames

So, you've introduced
react-router into your
single page React app as a way of managing routing. The app has started to
grow. There are many top-level routes for rendering different "pages". Some
of those "pages" now have sub-routing within them for managing wizard
workflows and sections with multiple "sub-pages". This is great. The dream
of routing within your React SPA has been realized.

Fast-forward a few months, and your elegant routing solution has become a brittle, error-prone maintenance nightmare. What happened?

A Simplified Example

Early into the development of a large React SPA, I noticed the above
scenario beginning to emerge. Some of what I noticed can be summarized in
the following series of code snippets. Note: these code snippets are not
full, working examples. Only the instructive parts have been included.

/* App.js */
return (
  <Switch>
    <Route path="/" component={Home} />
    
Continue reading "Managing React Router Pathnames"

Adventures in Mentorship

This fall, I participated in the formal mentorship program at the Code Platoon
bootcamp here in Chicago. In this post, I'd like to talk about my experience as a
mentor.

For the past few years, myself and a few Hashrocket colleagues have taught a
workshop at Code Platoon, focusing on test driven development, Ruby, and
PostgreSQL. As a veteran, it's one of my favorite days of the year, and I'm
grateful Hashrocket supports this outreach.

When Code Platoon put out a call for mentors this Summer to
work with the upcoming cohort, 'Golf Platoon', I decided to give it a try.

Why Mentor?

My drive to mentor comes from the fact that I have been mentored myself by many
great people. These advisors helped me find opportunities and direct my
professional growth. From the beginning, I hoped someday to be able to provide that same service to others.

I

Continue reading “Adventures in Mentorship”

Avoiding Code Catastrophes

"Am I going to make a huge mistake in my first dev job (e.g., delete the production database) and get fired?"

I've been asked this question a few times. It's a concern that new programmers have: that they'll end up in a situation where they make the wrong call in the heat of the moment, harming their company and ending their fledgling career. Cutting the red wire fixes the production bug; cutting the green wire sets our servers on fire, or vice versa. Which one will you cut, junior developer?

I think this is a valid fear when you're new, and it's something that once crossed my mind, as a self-taught beginner. Is it possible for me to make such a gigantic mistake in my first programming job? I think the answer is no.

When you start working as a developer you will have differing levels of

Continue reading “Avoiding Code Catastrophes”

Exploring the Default Postgres Template Databases

I was recently poking around the psql terminal, and noticed something that I had never had to deal with before: the Postgres template databases. I decided to seize the moment and launched myself into an exploration of what the template databases are meant to do, and why the heck there are two of them.

My first plan of attack was to just list them and see if I could find a difference right away, but everything looked exactly the same.

postgres=# \l
                                   List of databases
   Name   |   Owner  | Encoding |   Collate   |    Ctype    |   Access privileges
----------+----------+----------+-------------+-------------+-----------------------
postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + postgres=CTc/postgres
template1 | postgres | UTF8     | en_US.UTF
Continue reading "Exploring the Default Postgres Template Databases"

Where Am I: URL Assertions with Cypress

The URL that appears in the browser's URL bar is one of the first and
primary ways that users interact with our web apps. The URL tells the app
and the user of their location within the route hierarchy of the app. It
sometimes even contains state. The URL consequently serves as an excellent
first assertion when writing integration tests.

When writing Cypress integration tests, there are
several ways for us to assert about the current URL.

The cy.url() and
cy.location()
functions are the primary ways for us to gain access to information about
the current state of the URL. From there, we can perform a variety of
assertions.

We can assert about the entire URL:

// URL: http://localhost:8000/pokemon
cy.url().should('eq', 'http://localhost:8000/pokemon');
// ✅ passes

This is certain the most precise assertion. The tradeoff is that it requires
us to know something

Continue reading “Where Am I: URL Assertions with Cypress”

Wrap Parameters Without Changing Markup

While updating logic that caused a POST with a JSON body to change into a POST as multipart/form-data, I ran into an issue where the Rails controller was expected params in a nested way. Sure, I could change my inputs to have a different name that would cause the nested structure, but that was changing logic down the line.

Rails was wrapping the incoming parameters automatically since the prior request was of 'Content-Type': 'application/json'. Well, I'd really like this same behavior on my new request as it would solve my current conundrum.

Turns out ActionController has a method that can help out with that… the aptly named wrap_parameters method.

In my case, the name I needed was the same as the controller so I could use this:

class FooController < ApplicationController
  wrap_parameters format: %i[mutlipart_form json]
end

This produces a params payload like so:

ActionController::Parameters {
  "account_id_eq"=>
Continue reading "Wrap Parameters Without Changing Markup"

Query for NULL ‘or’ empty string in ActiveRecord

Sometimes you come across a query that looks for an attribute that is NULL 'OR' an empty string. Sure there are options we could employ that may remove the necessity of checking for both but let's see how we can improve our code a bit first!

The majority of the time I see this as a SQL fragment in ActiveRecord:

Foo.where("name is null or name = ''")

Which produces the following SQL:

SELECT * FROM "foos" WHERE (name is null or name = '')

Sure you can say now that ActiveRecord has or it could be done like so:

Foo.where(name: nil).or(name: '')

However, I'm currently in a project that doesn't support or yet so I went playing to see what I could come up with that wouldn't be a SQL fragment. My first thought was to

Continue reading “Query for NULL ‘or’ empty string in ActiveRecord”