Use fetch method to access ENV variables in Ruby

It's better for at least a couple of reasons, eloquently stated in this blog post by Michal Orman

...we can set default values or handle - providing a block - gracefully missing keys. Also using fetch with unknown key will raise KeyError that will tell us which exactly key is missing. That is in fact the behavior we are expecting from the app. Without required settings is just not working and complaining about missing setting and not about some random nil references.

Got that? Instead of this:

AWS.config(
  access_key_id:      ENV['S3_ACCESS_KEY'],
  secret_access_key:  ENV['S3_SECRET_KEY'],
  region:             ENV['S3_REGION']
)

Do this:

AWS.config(
  access_key_id:      ENV.fetch('S3_ACCESS_KEY'),
  secret_access_key:  ENV.fetch('S3_SECRET_KEY'),
  region:             ENV.fetch('S3_REGION')
)

Set defaults for JSONb postgres columns in Rails

Make sure to pass the migration a native Ruby hash as the default value. DO NOT pass it a string representation of an hash, thinking that it'll work (as valid JSON).

DO THIS

t.jsonb :preferences, default: {}, null: false

NOT

t.jsonb :preferences, default: '{}', null: false

It'll break in a maddeningly non-obvious way. Take my word for it. Also there is this relevant StackOverflow post which saved my ass.

Use Nodemon to auto-restart Rails server

The handy-dandy Nodemon tool is not just for Node. Today I whipped up an invocation that can restart my Rails server whenever there are changes in the config directory tree. Super useful when working heavily with i18n, since changing translation files requires bouncing the server to see changes reflected in the view.

$ nodemon --watch config -e rb,yml --exec "rails server"

Don't try to modify strings that come out of ENV

Today I woke up to an exception RuntimeError: can't modify frozen String

I looked at the code that had raised the exception. It was doing a gsub! on a value out of params. It took me a bit of digging to figure out why it failed. Turns out there's an edge case that causes one of those values to get pulled out of ENV instead of the normal flow where it originates from the user.

Strings coming out of ENV are frozen. D'oh!

Greenkeeper.io automated dependency management

This product just blew my mind, since I know how difficult it is to keep up with Node dependencies. You could manually track updates of your dependencies and test whether things continue to work. But it takes a lot of effort. So most of the time, your software is in a Schrödinger state of being potentially broken, and you have no idea until you run npm install and try the next time.

Greenkeeper handles the chores of dependency management. npm install and npm test is called immediately after an update. There is no doubt about the state of your software.

https://greenkeeper.io/

So you CAN disable swipe navigation in Chrome

Damn, I can't believe that I didn't think of disabling this dubious feature sooner. Can't even begin to tell you how often an errant fingertip brush makes my Chrome history go backwards (or forwards, for that matter). Turn that shit off with the following command in your terminal.

defaults write com.google.Chrome AppleEnableMouseSwipeNavigateWithScrolls -bool NO

Make sure to restart Chrome for it to take effect.

Clearfixing is much easier these days

Hadn't needed to do a clearfix in awhile and thought I would have to do something like this:

.container::after {
    content:"";
    display:block;
    clear:both;
}

Or even worse...

.container::before, .container::after {
    content:"";
    display:table;
}
.container::after {
    clear:both;
}
.container {
    zoom:1; /* For IE 6/7 (trigger hasLayout) */
}

Then I was pleasantly surprised to learn that on modern browsers you just have to set the overflow property to auto on the containing element and you should be good to go.

.container {
  overflow: auto;
}

Why Capybara requires button for submitting forms

Despite being a super common request, Capybara's API doesn't give you a way to submit forms directly (without hitting a submit button). The denial to do so is actually a principled stance, as you can read for yourself in this pull request. In a nutshell, Jonas believes its a bad practice to do so, plus there is no standard way to support the functionality across all browsers.

Workarounds exist, but seem clunky.