Archive 2019

October 16, 2019

Rails 6 introduces a new auto loader called zeitwork. The literature has me convinced transitioning to this new loader will be worth the effort. The legacy of the Rails apps we’ve built has us opting for the :classic loader in the immediate.

A nice thing about using :classic, is that Rails provides some deprecations that point toward getting ready for :zeitwork. As an example, autoloading constants in an initializer (config/initializers/[something].rb) emits a deprecation warning in Rails 6.

DEPRECATION WARNING: Initialization autoloaded the constants Sortable, Foldable, and Launderable.

Being able to do this is deprecated. Autoloading during initialization is going to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during initialization does not run again. So, if you reload Sortable, for example, the expected changes won't be reflected in that stale Class object.

`config.autoloader` is set to `classic`. These autoloaded constants would have been unloaded if `config.autoloader` had been set to `:zeitwerk`.

Please, check the "Autoloading and Reloading Constants" guide for solutions.

Following the Autoloading and Reloading Constants guide, and some supplementary Duck Duck Go’ing, I learned about the Rails.configuration.to_prepare API. Where initializers run once when the app is booting, blocks passed to to_prepare will be run before every request in development, and once before eager loading in production.

For a handful of constants that are being autoloaded in an initializer, using to_prepare did the trick.

-ActiveRecord::Base.send :include, Sortable
+Rails.configuration.to_prepare { ActiveRecord::Base.send :include, Sortable }

October 3, 2019

I’m intentionally slow to script things away in my day-to-day development. I understand the benefits of scripting away repetitive tasks. But I’ve found that they come at the cost of empathy.

I used to have an alias of be for running bundle exec. When I’d pair with newer developers, they’d begin to think that be is a command they should know, when in fact it was a customization they’d need to borrow. So I’ve formed the habit of always typing out bundle exec.

It takes a little more time. But when someone is looking over my shoulder, they’re learning how to do do the thing rather than learning my abstraction about how to do the thing.

September 27, 2019

While authoring a very boring HTML form I learned that you do not need a for/id pair on a label that is wrapping a radio input.

-<label for="radio_option_1">
-  <input id="radio_option_1" type="radio" name="cheese" value="cheddar"> Cheddar
+  <input type="radio" name="cheese" value="cheddar"> Cheddar

September 26, 2019

React Native’s <StatusBar /> component behaves similarly to <Helmet /> from react-helmet. Render them anywhere in the tree. Every time an element is rendered, it’s props get pushed onto the top of a stack that will reconcile as a cascade of props for imperatively updating outside values.

The source of StatusBar.js was particularly helpful, because I discovered it just as I was arriving at a near-identical solution for doing something similar in an app I’m working on.

September 18, 2019

git rebase --exec is a handy tool for ensuring that each commit is keeping the tests passing.

Ensuring that each commit keeps the tests passing is in service of an ideal I’ve been pursuing. I don’t like submitting commits with the phrase “fix tests” in the description. I like refactoring old functionality or introducing new functionality under green tests.

To do this, I tend to work in two phases lately.

Phase one is an exploratory branch where I’m figuring things out. This is me thrashing through the jungle with a machete.

Phase two is a refined branch, where I’m communicating to others what I figured out. This is more surgical with detailed commits, explaning what changed, why, and alternatives that were considered in my exploratory thrashing branch.

Before submitting phase two for consideration, I’m starting to get in the habit of making sure the tests passed each step of the way.

$ git rebase --exec "bin/rails test" master

That will run the Rails tests on every commit that contributed to the current branch.

August 19, 2019

React’s Developer Tools are accessible from Safari!

For the last three years I’ve been developing day-to-day in Safari. Whenver this practice comes up in conversation the first question is “what about React Developer Tools?” Until today my answer was to drop into Chrome.

Today I discovered that react-devtools can be launched as a standalone application that can be connected to.

I wired this up in my Rails app with some development only logic.

<% # app/views/application.html.erb %>
<% if Rails.env.development? && ENV["CONNECT_TO_REACT_DEVTOOLS"] == "yep" %>
  <%= javascript_include_tag "http://localhost:8097" %>
<% end %>

With this in place, starting a Rails server with the appropriate environment flag does the trick. bin/rails server CONNECT_TO_REACT_DEVTOOLS=yep

August 1, 2019

Updating for security vulnerabilities with yarn can be tricky. For example, I got a Github warning that my version of js-yaml needed to be updated. js-yaml does not appear in my package.json. It is one of my dependencies’ dependencies.

yarn update js-yaml@secure-version adds js-yaml into my dependencies, which is not what I want to communicate to the team.

Trying to solve for this communication problem brought me to Yarn’s selective dependency resolutions. This seems to fit the exact bill of what I’m trying to achieve. Among the reason’s to use selective dependency resolution is listed:

A sub-dependency of your project got an important security update and you don’t want to wait for your direct-dependency to issue a minimum version update.

Force yarn.lock to update appropriately, without communicating to a future maintainer that this is actually a dependency of our app. Works on my machine.

January 11, 2019

Use date.to_s(:db) when you need to use a date in a Rails YAML fixture. My muscle memory reached for date.format(:db), but that’s wrong. It’s .to_s

  last_wanted_cookies_at: <%= 1.second.ago.to_s(:db) %>