Rails: When Changing Code Doesn't Change Behavior

Matheus Richard

We’ve all been there. We’re updating the code, but nothing changes (either in the UI or in the back-end). Here’s a list of things to check to figure out what’s wrong.

Check Your Environment

I’m particularly guilty of this one. I’ve spent time figuring out why my changes weren’t being reflected, only to realize I was looking at the wrong tab (production, not development).

To avoid this, here are two tips to help you differentiate between environments:

  1. Use a different favicon for each environment: This is an easy old trick, but it works like a charm. Here’s a tutorial on how to do it.
  2. Use a custom IRB/Pry prompt for each environment: This will help prevent you from running commands on the wrong environment. Here’s how you can do it with IRB and here’s how you can do it with Pry.

Also, make sure you have the appropriate RAILS_ENV value set.

Check your Feature Flags

You might not have the correct feature flag enabled for your environment. That can cause entire chunks of code to be skipped. It’s hard to give advice here since there are many tools for feature flags, but using a debugger or a raise is often enough to determine if you’re hitting the correct code path.

if Feature.enabled?(:my_feature)
  raise "Feature flag enabled"
  # ...
else
  raise "Feature flag not enabled"
  # ...
end

Watch Your Files

You might have your asset pipeline set up to bundle JS and CSS files and do all sorts of processing. Because of that, your development environment might contain file watchers that will automatically update the generated files when you change the source files. In that case, you want to make sure you’re running the file watcher:

yarn build:css --watch
# and/or
yarn build --watch
# or
bin/webpack-dev-server

Another thing to check is if the watcher is watching the files you’re changing. This is very common when working with Tailwind CSS, for example. Check if you have all your view/helper/component/JS files in the content array in tailwind.config.js:

module.exports = {
    content: [
        './public/*.html',
        './app/helpers/**/*.rb',
        './app/javascript/**/*.js',
        './app/views/**/*',
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

Clear Generated Assets

From time to time, you might run rails assets:precompile to test your asset pipeline. That will generate files in public/assets, and those files take precedence over the ones in app/assets. So, when you update your CSS or JS, you won’t see any changes.

To clear the generated assets, run:

rails assets:clobber

After that, Rails will use the files in app/assets again.

Disable Spring

Spring is a gem that used to ship on Rails by default so it’s still likely to be found in several projects. It preloads your app, so it’s faster to run the server/tests.

Ask anyone who’s worked with it, and they’ll tell you that someday it caused a weird bug that took a long time to figure out. Caching invalidation is indeed a hard problem in Computer Science, so if you think you’ve found a bug, try shutting it down manually:

bin/spring stop

Some people just remove it from the project altogether.

Delete Cache

On that note, there are other types of caches in your Rails app. Here’s a list of things to try:

rails tmp:cache:clear # Clears the entire cache
# or
rails tmp:clear # Clears session, cache, and socket files from tmp/

Your browser also caches things, so you might want to try clearing that as well. In most browsers, you can do that by pressing Ctrl + Shift + R or Cmd + Shift + R.

Restart The Server

An old-time classic! And that’s for a reason: it works! Now, there are several reasons why you might need to restart the server:

  1. Code that only runs during application boot: There are a few edge cases in Rails where you need to restart the server for a change to take effect. Some examples are updating middlewares and when a new separate Single Table Inheritance hierarchy is added to the application.
  2. Stale code: Maybe you changed branches and the server is still running the old code, or maybe some of the file watchers don’t pick a new config unless you restart them. These might be bugs or limitations of the tools you use.

This technique is also a quick way to narrow down the problem. If you stop the server but the app is still running, something is wrong (you’re running multiple instances, or looking at the wrong tab, etc).

Looking At The Wrong Place

Sometimes things are, in fact, changing, but you’re not looking at the right place or you can’t see them. Things to check:

  • Something covering the change:
    • The text and background have the same colors, so you don’t see the text;
    • Z-index is not set correctly, so something is covering the change;
    • You have something covering part of your computer screen and you can’t see the change when it happens;
      • This is more common than you might think. Be careful with things on the edges of your screen!
  • Errors: Errors are being logged in the console, but you’re not looking at it. For instance, you might have missed a turbo frame, so your updates will not be reflected in the UI. Turbo will warn you about that in the console.

Challenge Your Assumptions

One of the assumptions we often make is that we’re editing the right file. Adding a raise or a puts to the file you’re editing is a quick way to check that. Rails can also annotate your view files with comments, so you know which parts of the HTML were generated by which files.

If you want to learn more about debugging in general, here’s a series of posts that can help you. Good luck!