---
title: "Basecamp's privacy-aware Rails console"
publication: "Ruby Weekly"
issue: 567
published_at: "2021-08-26"
canonical_url: "https://rubyweekly.com/issues/567"
---

Plus decomposing a monolith, responsible monkeypatching, and using 'extend'. |        

#​567 — August 26, 2021 

[Read on the Web](https://rubyweekly.com/issues/567)    

Ruby Weekly 

[![\](https://res.cloudinary.com/cpress/image/upload/w_1280,e_sharpen:60/j7jxxp1i5nrs8bhkz1ui.jpg)](https://world.hey.com/jorge/privacy-aware-rails-consoles-with-console1984-and-audits1984-53562eaa)  

[Privacy-Aware Rails Consoles with console1984 and audits1984](https://world.hey.com/jorge/privacy-aware-rails-consoles-with-console1984-and-audits1984-53562eaa) — Basecamp created [console1984](https://github.com/basecamp/console1984) to protect sensitive/encrypted data in a console connected to production. The [audits1984](https://github.com/basecamp/audits1984) gem provides a UI (Rails engine) to examine the logs created by_console1984_. 

Jorge Manrubia (Basecamp)   

[A Tour of Twist](https://ryanbigg.com/2021/08/a-tour-of-twist) — Twist is a Hanami-inspired Ruby application that Ryan uses to expose his nascent books to reviewers for notes and suggestions. It uses dry-rb components, ROM, and many off-the-Rails-path items. 

Ryan Bigg   [![\](https://copm.s3.amazonaws.com/f80cbe92.png)](https://pganalyze.com/ebooks/postgres-indexing?utm_source=RubyWeeklyPrimary08262021) 

[Free eBook: Effective Indexing in Postgres](https://pganalyze.com/ebooks/postgres-indexing?utm_source=RubyWeeklyPrimary08262021) — Learn how to create the best Postgres index for your queries. We provide a deep dive into index types, operators, data types and more. Creating the right indexes can often improve your query performance by 10x or even 100x. 

pganalyze sponsor   

**QUICK BITS:** 

- [RubyMine 2021.2.1](https://blog.jetbrains.com/ruby/2021/08/rubymine-2021-2-1-is-available/) is available.
- The [latest monthly update from Ruby Together](https://rubytogether.org/news/2021/8/july-2021-monthly-update) covering RubyGems and [rubygems.org](https://rubygems.org/) news.
- React and Rails seem to be [increasingly paired up in job posts](https://matthewbellantoni.com/2021/08/17/react-is-now-effectively-part-of-the-rails-stack/). Is React becoming a de facto part of the 'Rails stack'?   

▶[Decomposing a Massive Rails Monolith with Shopify's Kirsten Westeinde](https://about.sourcegraph.com/podcast/refactoring-shopify-codebase-kirsten-westeinde/) — We’re not all going to have the opportunity to decompose a giant monolith, so listening to how Shopify handled it with tools, practices, and trial and error, along with what they learned, is fascinating. 

Sourcegraph podcast     

Jobs  

[Senior Software Engineer (Remote in the US)](https://grnh.se/bf97c4df4us) — Snapdocs is now a [Unicorn](https://snapdocs.com/press/snapdocs-named-to-the-2020-cb-insights-fintech-250-list-of-fastest-growing-fintech-startups/) with a $1.5B+ valuation. We’re a SaaS product disrupting the mortgage and real-estate industry. Join our growing distributed team. ROR, Go, Postgres, React, AWS. 
Snapdocs   

[Full Stack Engineer (Rails, New York)](https://angel.co/company/dovetale/jobs/483906-full-stack-engineer-rails) — Dovetale helps Shopify merchants like KontrolFreek and Italic grow their creator community. Built in NYC and backed by Uber founders. 
Dovetale   

[Find Ruby Jobs Through Hired](https://hired.com/join/?utm_source=newsletter&utm_medium=sponsor&utm_campaign=%28b2c%29%28l-all%29%28r-all%29%28cooper-rubyweekly%29&utm_content=find-your-next-job) — Create a profile on Hired to connect with hiring managers at growing startups and Fortune 500 companies. It's free for job-seekers. 
Hired    

📕 Articles & Tutorials 

[![\](https://res.cloudinary.com/cpress/image/upload/w_1280,e_sharpen:60/xtusmmzxcn3asq5q7edz.jpg)](https://blog.appsignal.com/2021/08/24/responsible-monkeypatching-in-ruby.html)  

[Responsible Monkeypatching in Ruby](https://blog.appsignal.com/2021/08/24/responsible-monkeypatching-in-ruby.html) — Yes, yes…we all understand that monkeypatching isn’t always the _best_ idea but it’s sometimes unavoidable, so having a defensive (and quite involved) approach can save your bananas later. 

Cameron Dutro (AppSignal)   

[An Introduction to `jq` for JSON Wrangling](https://earthly.dev/blog/jq-select/) — jq is a fast, C-powered command-line utility to parse, sort, filter, and do just about anything with JSON data. Adam’s post is now the place to go to to remember `jq` syntax instead of Googling it. 

Adam Gordon Bell   

[Submitting Many ActionMail Jobs at Once with Sidekiq](https://wjwh.eu/posts/2021-08-24-sidekiq-rails-bulk-push.html) — ActionJob does not expose a bulk submission method and, by default, will create loads of connections when you submit many jobs, but we (and Wander) can fix that. 

Wander Hillen   

[How to Send Emails with Ruby](https://www.courier.com/blog/tutorial-how-to-send-email-in-a-ruby-app?utm_campaign=newsletters&utm_source=ruby-weekly&utm_medium=send-emails-ruby) — In this tutorial, we’ll show you the way to add email functionality to your Ruby app focusing on transactional triggers. 

Courier sponsor   

[Notes on Retrying All Jobs with ActiveJob `retry_on`](https://bibwild.wordpress.com/2021/08/23/notes-on-retrying-all-jobs-with-activejob-retry_on/) — An argument for using `ActiveJob#retry_on` for all errors (even if DHH says that’s bad) and how to get it going with Resque. 

Jonathan Rochkind   

[Better Ruby Gemfile Security: A Step-by-Step Guide using Snyk](https://snyk.io/blog/better-ruby-gemfile-security-step-by-step-guide-snyk/) — This is more about scanning popular Ruby gems and listing their vulnerabilities along with how to address each one. 

Snyk   

[Run RuboCop on `git commit` with Overcommit](https://prabinpoudel.com.np/articles/run-rubocop-on-git-commit-with-overcommit-gem/) — A simple tip. [Overcommit](https://github.com/sds/overcommit) is a git hook manager. 

Prabin Poudel   

▶[Brittany and Jemma Talk Life Stories and Some of Their Favorite Things](https://www.therubyonrailspodcast.com/381) — The _Ruby on Rails Podcast_ takes a cosier, more personal tone this week with Jemma (who writes our _Tip of the Week_!) and Brittany (the main host) talking about how Jemma is joining Shopify (congrats!), their favorite developer tools, and the [WNB.rb](https://twitter.com/wnb_rb) Ruby user group. 

The Ruby on Rails Podcast podcast   

[Diggin’ and Fetchin’ with TruffleRuby](https://shopify.engineering/dig-fetch-truffleruby) — Sometimes the largest journeys start with the smallest steps, like here where a small refactor ballooned into finding a bug in TruffleRuby along with a potential contribution to the language. 

Julie Antunovic (Shopify)  

🛠 Code & Tools  

[oktest: A New Testing Library for Ruby](https://github.com/kwatch/oktest/blob/ruby/ruby/README.md) — oktest is a new spec-like testing library that has an impressive amount of features with a claim of “good performance”. I love the clean style of the assertions. 

kwatch   

[Modularity: Traits and Partial Classes for Ruby](https://github.com/makandra/modularity) — Enhances `Module` so it can be used to define traits and partial classes which can make your meta-programming experiences better. 

makandra   

[Crunchy Bridge: Fully Managed Cloud Postgres](https://www.crunchydata.com/products/crunchy-bridge/?utm_source=Ruby+Weekly&utm_medium=newsletter&utm_campaign=Bridge&utm_id=crunchy+bridge&utm_content=8-26-21) 

Crunchy Bridge sponsor   

[wipe_out: Library for Resetting Data in Rails ActiveRecord Models](https://github.com/GlobalAppTesting/wipe_out) — wipe_out allows you to create a “plan” that will remove, reset, or generate and overwrite data for a given schema. The first use case I thought of was sanitizing production data for a test environment. 

Global App Testing   

[Standard 1.2: A Ruby Style Guide, Linter and Formatter](https://github.com/testdouble/standard) — As [StandardJS](https://standardjs.com/) is to JavaScript, Standard is to Ruby. 

test double   

[Futurism 1.0: Lazy-Load Rails Partials via CableReady](https://github.com/stimulusreflex/futurism) 
StimulusReflex   

[SearchKick 4.6: Intelligent Search Made Easy with Elasticsearch](https://github.com/ankane/searchkick) 
Andrew Kane   

[Restforce 5.1: A Ruby Client for the Salesforce REST API](https://github.com/restforce/restforce) 
Restforce       

💡**Tip of the Week** 

   

## Extend 

[Last week](https://rubyweekly.com/issues/566), we learned something important about singleton classes: class methods are instance methods on a class' singleton class. Let's take a step back though - how is this relevant to `extend`? 

We already know that [`include`](https://rubyweekly.com/issues/564) inserts a module into the class' [ancestors chain](https://rubyweekly.com/issues/563) right after the class that `include`s it and [`prepend`](https://rubyweekly.com/issues/565) inserts it right before. Well, `extend` also inserts a module into an ancestors chain, but it does this on the ancestors chain of the [singleton class](https://rubyweekly.com/issues/566) of a class (not the class itself): 

```
module ExampleModule ; end

class ExampleClass
  extend ExampleModule
end

ExampleClass.ancestors
=> [ExampleClass, Object, Kernel, BasicObject]

ExampleClass.singleton_class.ancestors
=> [#<Class:ExampleClass>, ExampleModule, #<Class:Object>,
#<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
``` 

The `#<Class:ExampleClass>` syntax means it's the singleton class of `ExampleClass`. We can see that`ExampleModule` is inserted into `ExampleClass`'s singleton class' ancestors chain. 

Let's combine this with what we've learned about singleton classes - instance methods on a class' singleton class are class methods on that class. So say we had an instance method defined on `ExampleModule`: 

```
module ExampleModule
  def example_module_instance_method
    "This is an instance method defined on ExampleModule"
  end
end
``` 

If we `extend ExampleModule` it will become a _class method_ on `ExampleClass`: 

```
class ExampleClass
  extend ExampleModule
end

ExampleClass.example_module_instance_method
=> "This is an instance method defined on ExampleModule"
``` 

If we had instead used `include` on the same `ExampleModule`, this would remain an instance method: 

```
class ExampleClass
  include ExampleModule
end

ExampleClass.new.example_module_instance_method
=> "This is an instance method defined on ExampleModule"
``` 

Nice! We've now learned three ways to use code from a module in a class: 

- [`include`](https://rubyweekly.com/issues/564) inserts a module into the class' ancestors chain right after the class.
- [`prepend`](https://rubyweekly.com/issues/565) inserts a module into the class' ancestors chain right before the class.
- `extend` inserts a module into the class' singleton class' ancestors chain right after the class, meaning essentially all of the module's instance methods can be accessed as if class methods on the class which extends it.    

This week’s tip was written by [Jemma Issroff](https://twitter.com/jemmaissroff).    

🎨 A Fun One..  

[PNGlitch: A Ruby Library to Glitch PNG Images](https://github.com/ucnv/pnglitch) — This isn’t just a visual effect applied to your image - the data is actually ‘glitched’ but the checksums are updated to make them still render. This means the result is rather.. dramatic. 

ucnv         

Curated by [Peter Cooper](https://twitter.com/peterc), [Glenn Goodrich](https://twitter.com/ruprict) and [Cooperpress](https://cooperpress.com/). 

[Change your email address](https://rubyweekly.com/edit_subscription/*|UID|*) or[Stop getting this newsletter](https://rubyweekly.com/leave/*|UID|*) 

© Cooper Press Ltd · Fairfield Enterprise Centre, Louth, LN11 0LS, United Kingdom
