It was a regular Monday morning. I was sipping coffee waiting to head into standup when I got a slack

I messed up.... I accidentally ran User.update(admin: true) when trying to update my account, and updated every user in the system

At first, disbelief, then, panic. Firefight mode starts. I spin up a database backup, generate a list for us to revert back to, and the crisis is quickly solved.

This however, started the search for a better production console. We're still a pretty small team, at an early stage company. So we didn't want to shut off rails console access entirely. However, there has to be a better way to make sure we don't typo or goof.

Enter, Safeconsole

Utilizing pry, safeconsole wraps every session in a database transaction, and rolls it back unless otherwise told to.

Here's what it looks like when you enter a safeconsole session with rails safeconsole

  ______          __     ___
 /_  __/__  _____/ /_   /   |  ____  ____
  / / / _ \/ ___/ __/  / /| | / __ \/ __ \
 / / /  __(__  ) /_   / ___ |/ /_/ / /_/ /
/_/  \___/____/\__/  /_/  |_/ .___/ .___/
                           /_/   /_/

Current Rails Env: development

Welcome to safeconsole, you're in good hands.

Usage:
  - refresh: Load a new transaction (and commit if configured)
  - commit: Set this transaction to be commited to the DB on refresh/exit
  - nevermind: Set this transaction to be *discarded* on refresh/exit
  - stats: Print the current transaction and session stats (commit status, length, stats)
  - commands: Print command instructions again

Hotkeys:
  - ctrl+d: Load a new transaction (equivilent to refresh)

You're a wizard, searching for a long lost artifact.
You begin casting a locating spell
[1] safeconsole(Safeconsole::Console)>

This allows you to modify the database, and check your changes before comitting the modifications.

We've been using it at ROH for about a year now, and it's helped us quite a bit. When building it, I figured 90% of our console usage was read only queries, so it made sense to be safe by default.

There are more configuration options, and details at the Github Repo