Matthew Lindfield Seager

Thank you to the Ruby Central team for organising the COVID-19 version of RailsConf… RailsConf 2020.2 - Couch Edition (https://railsconf.com)

I plan to do short write-ups of each talk I watch to help cement what I learn.

I’ve used Zoom, Cisco WebEx, MS Teams, Slack and GoToMeeting for video calls or meetings of late. The Zoom experience was superior EVERY time.

But installing backdoors on Macs last year and exfiltrating iOS user data to Facebook this year makes me question Zoom’s company culture

I hoped to reinvent myself through this lockdown period… like maybe the change of routine and circumstance would be a catalyst for rapid change.

Cue: disappointment.

I often hope for a dramatic change, even though I know small, consistent, compounding changes are required.

Today I learned you can show hidden files and folders in the macOS finder with the keyboard shortcut Command-Shift-period (⌘ ⇧ .)

And researching it more, apparently this key combo got expanded to the Finder in Mojave, it has always worked in open/save dialog boxes 🤯

Today I learned you can use git to compare files, even if they aren’t in a repo!

git diff --no-index file1.txt file2.txt

An issue with Spring caching lead me on a journey of discovery

TLDR; I spent quite a while trying to figure out why ENV variables weren’t being loaded by dotenv-rails. Reloading spring with spring stop was the surprise fix. I learned a lot in the meantime, and since!


I decided to encrypt all personally identifying information (e.g. names and email addresses) in an app I’m hacking away on. It won’t protect them if the application server gets compromised but it adds some protection for the data at rest (you might be surprised how often data is compromised from logs or backups).

Encryption keys are part of an apps configuration and as such, I learned, they don’t belong in the code. In production I will manage the encryption keys through Heroku config vars but I wanted a simple way to manage environment variables in development so I chose dotenv (via the dotenv-rails gem).

Once I had the gem installed and my .env file populated, I fired up the Rails console and was surprised my variables weren’t in ENV. Manually running Dotenv.load worked so I knew the gem was installed and my .env file was able to be found.

After restarting the console a couple more times, the next thing I tried was adding Dotenv::Railtie.load to config/application.rb as per the instructions on making it load earlier. I fired up the console again and they STILL weren’t loaded.

I’d looked through the code on Github and felt like I had a pretty good understanding of what should be happening (and when) but it wasn’t behaving as documented.

At this point I felt like I needed to debug what was going on inside the gem so I figured out how to get the local path to the gem (bundle show dotenv-rails - thanks Stackoverflow!) and then opened the gem in my text editor. In fish shell that can be combined into a single command:
atom (bundle show dotenv-rails)

From there I did some caveman debugging and added puts statements to #load and #self.load to see if I could see them being called. I then restarted the console… still nothing. But now that I had access to the gem I could start testing with rails server rather than rails console. I restarted my dev server and straight away saw:

`self.load` got called
`load` got called
`self.load` got called
`load` got called
=> Booting Puma
=> Rails 6.0.2.1 application starting in development

Sure enough, it works when I start the server (twice, thanks to my addition of Dotenv::Railtie.load) and so the problem is only in Rails console.

After some more digging around in the Github issues I found some reference to a similar problem being caused by spring. As soon as I ran spring stop and restarted the console it worked.

To get to the bottom of this issue I started researching Spring but according to the README, changing the Gem file AND changing config/application.rb should both have caused Spring to restart.

I’ve opened an issue on Spring to see if anyone can help me figure it out but in the meantime I’m happy to have learned a fair bit…

Lessons Learned

  1. Config belongs in the environment, not in the code: https://12factor.net/config
  2. The dotenv gem makes managing environment variables simple (including support for different variables in different environments)
  3. You can find a Gem’s installation path with bundle show <gem-name>
  4. You can’t pipe the output of that command to open the gem in Atom (at least in fish shell) but you can run it as a sub-command using brackets: atom (bundle show dotenv-rails)
  5. Spring is a built-in rails mechanism for caching the application to speed up boot times in development (particularly console and tests)
  6. You can restart Spring with spring stop or by closing your terminal (the next time you launch something it will start again)
  7. You can tell Spring which files to watch by editing the config/spring.rb file

Just read that Bob will take over from Bob as CEO at Disney. Interestingly, there are as many Alans on the Disney board as there are women (three of each).

Reminds me of a diversity report on ASX200 CEOs; 32 Johns, 32 Peters, 21 Davids and 19 women

I’m reluctantly trying to sign up for Facebook so we can post micro.blog updates to friends and family during some upcoming travel.

I’ve registered with a dedicated email but now Facebook “checkpoint” won’t let us go any further without providing a mobile number 🙄

No thanks!

Finished listening to MatchUp this morning. Collection of 11 short stories written by pairs of well known thriller writers. 📖 🎧

Great stories! And I discovered some new authors to read!!!

www.goodreads.com/book/show…

Yesterday I learned you can update a single gem without updating dependencies using bundle update --conservative gem-name

If that update REQUIRES another gem to be updated I’m told you can include just it: bundle update --conservative gem-name other-gem

Thoughtbot: Name the Abstraction, Not the Data - thoughtbot.com/blog/name…

This makes a lot of sense to me. Sacrifice a small amount of DRYness (potentially) to increase clarity and loosen coupling.

📖 Force of Nature - Jane Harper (https://www.goodreads.com/book/show/34275222-force-of-nature)

Set in the Aussie bush, this was an intriguing mystery story and very well told.

(This is the 4th of 5 books I read on a cruise recently)

📖 Alex Cross’s Trial - James Patterson and Richard Dilallo (https://www.goodreads.com/book/show/6266907-alex-cross-s-trial)

This isn’t an Alex Cross book, nor (arguably) a James Patterson book. Despite the cynical marketing ploy, it was a pretty good, albeit dark at times, read

📖 Bad Luck and Trouble - Lee Child (https://www.goodreads.com/book/show/108942.Bad_Luck_and_Trouble)

Another enjoyable Jack Reacher novel. Lots of action and intrigue… and the baddies seemed like more formidable opponents than others he has faced.

📖 Scarecrow and the Army or Thieves by Matthew Reilly - www.booktopia.com.au/scarecrow…

Over the top, ridiculous and impossible to believe. Exactly what I was hoping for to start my holiday reading 🙂

Is Your Ticketing System a Tool or a Weapon?

In the hands of a carpenter, sportsperson or chef, hammers, bats and knives are all useful tools. In other hands, or even just other circumstances, they are useful weapons. In fact, just about all tools and technologies can be used constructively or destructively.

A ticketing system is no exception. At its best, a ticketing system helps agents collaborate, facilitates communication with customers and ensures issues aren’t forgotten.

At its worst, a ticketing system can be gamed by agents to avoid work they don’t like (or colleagues they find annoying), they can be weaponised by customers to prove how poor the service they received was or they can simply devolve into a distraction from the actual work of helping people.

Some quick rules of thumb I have for running a ticketing system are: - never ask someone who has just told you about a problem to log a ticket… they made the effort to visit you or call you to tell you there’s a problem, don’t make them tell the story all over again to an impersonal ticketing system - focus on solving their problem, not closing the ticket. If the problem is solved and the customer is happy, the ticket can stay open forever for all I care, just as long as it doesn’t stop you from noticing the next ticket - don’t use the ticketing system as a wishlist or backlog. Anything that hasnt been touched for two weeks (and probably isn’t going to be in the next two weeks) doesn’t belong in the ticketing system; it just gives the customer false hope and the agent unnecessary stress - if you can fix it straight away, just do it, no ticket required. We’re here to solve problems, not track time or put notches in our belts - try to fix problems and have conversations in person (or at least on the phone). Put a (very brief) summary of the conversation or solution in the ticket for collaboration/posterity - find ways to measure what matters, rather than what’s easy to measure - ignore any or all of these rules when doing so makes more sense or gives the customer better service

A Tale of Two MacBooks

My 2016 MacBook Pro had keyboard problems within about 6 months.

My 2019 MacBook Air (less than 5 months old) is having keyboard problems.

My MBP was owned by work and came with an on-site (edu) warranty.

My MBA is owned by me and has a back to base warranty.

I kept using my MBP right up until the tech arrived… and I had it back in less than an hour!

My MBA will be out of action for a predicted 5-7 business days.

My livelihood as a salaried employee was completely independent of my MBP. If it failed, I would still have been paid (AND I could have immediately borrowed another Mac from work).

My livelihood as a self-employed contractor is highly dependent on my MBA. To be without it for over a week is hugely inconvenient and potentially very costly.

Despite (or perhaps because of) my MBP experience, I used to think the tech uproar about Apple’s keyboard problems was overblown. After all, “it’s only affecting a small percentage of users” and Apple (Unisys) fixed mine almost instantly.

Now that I’m experiencing it on my almost new MBA with a third generation butterfly keyboard, and facing more than a week without THE crucial part of my toolkit, I’m feeling a lot less forgiving.


It’s just a shame my 2010 MacBook Pro can’t run a modern operating system! Other than dreadful battery life and a spongey trackpad its hardware is still going strong! (Including the keyboard, despite spending six months in the dust and grime of Afghanistan, a literal war zone)

I had a couple of hours to kill in Parramatta so I dropped into UWS’ new building near the station. They had lots of good workspaces, comfortable furniture, plenty of 240V/USB power outlets and clean facilities 👍

The table tennis table in the quiet zone made me chuckle though

The Internet generally and YouTube specifically can be pretty amazing!

This evening I was told I needed to learn how to make balloon animals… in 45 minutes I progressed from zero to confidently (even if not competently) making dogs, swords and even 2 colour flowers!

Two items for the “you could but probably shouldn’t” category and Postgres:

Scripts to Rule Them All

Today I configured a new Rails app with Scripts to Rule Them All. It’s a “normalized script pattern that GitHub uses in its projects” to standardise projects and simplify on-boarding. It’s probably premature for an app I’m working on solo… but if you can’t experiment on side-apps, when can you? 😜

I ran into a catch-22 where, the first time you setup the repository, the setup script tries to initialise the database, which relies on the database server being available. The support script that starts the database relies on the setup script (or more specifically, the bootstrap script it calls) already having been run to install the database server. But the setup script relies on the support script… etc, etc

Rather than get fancy I decided to let the developer deal with it. The setup script is idempotent so there’s no harm in running most of it the first time and then all of it the second time. After DuckDuckGoing how to check if Postgres is running and how to write if/else statements in shell scripts I settled on this clause in the setup script:

if pg_isready; then
  echo "==> Setting up database…"
  bin/rails db:create db:reset
else
  echo "==> Postgres is not running (this is normal on first setup)."
  echo "==> Launch ‘script/support’ in another console and then try again"
  exit 1
fi

echo "==> App is now ready to go!"

I’ve been helping with a POS implementation on Vend (https://www.vendhq.com/).

It’s just a delightful application to use with amazing attention to detail! The way they gracefully handle data imports is a great example of how they understand what their customers need.

While searching for my POODR ebook, I stumbled across some notes I wrote last time I read it… I took notes and I still don’t remember reading it! 😬

This (U.S.) thanksgiving weekend I’m thankful that several podcast hosts are having a break, letting me catch up on my backlog a little 😆

I’ve been enjoying reading Noah Gibbs’ thoughts on deliberate coding practise:

codefol.io

Following his encouragement, I think my next book will be 99 Bottles of OOP