Active Record dirty tracking in after_commit hooks

Rails provides a convenient way to track changes in Active Record models with the ActiveRecord::AttributeMethods::Dirty module. This allows us to check what changes are going to be persisted to the database or the latest changes that were persisted. These methods can be useful in Active Record hooks so that you can run certain hooks only when certain attributes change.

Read more

A Bundler problem

Last week, we had a tricky Bundler loading issue at work so I went into a deep dive into the Bundler and RubyGems source code and learned a few things.

The problem

We have a parent process that spawns multiple Sidekiq processes using bundle exec sidekiq. Now we want to setup the Bundler environment in the parent process because we want it to load some dependencies. It seems straightforward but we ran into a very cryptic error message when running the child processes:

Gem::LoadError: ed25519 is not part of the bundle. Add it to your Gemfile.

This was very confusing because ed25519 was definitely part of our Gemfile although it was in a non-default group. And this was working fine before we loaded Bundler in the parent process. How could loading Bundler on one Ruby process affect another Ruby process?

The answer turned out to be simple: Bundler alters environment variables when it is loaded. This is also documented in https://bundler.io/man/bundle-exec.1.html#Shelling-out. So simply wrapping the system call with Bundler.with_original_env fixed the problem.

It took many hours to figure that out but in the process, I also learned more about how Bundler works and how we ended up with that error message.

Read more