Finding your way around Rails code
Tags: rails, webdev, debugging, vscode
Published: 2023-12-11 17:40:58

In Ruby on Rails, it can be really difficult to figure out where you are in the code, since Rails conventions dictate using the same file names over and over (`new.html.erb`, `show.html.erb`, etc.). Here are a couple hacks to make it easier.

Note: Parts of this guide assume you're using VS Code, but some of it should work for any IDE.

## Adding the file path to VS Code tabs

It's hard to tell where you are in the application from looking at the file tab in VS Code. But we can add the path to the tabs to show us the parent folder. Here's how:

- Hit `CMD+Shift+P` to open the Command Palette
- Begin typing `JSON` and navigate to `Preferences: Open User Settings (JSON)`
- Add this line: `"workbench.editor.labelFormat": "short",`
- Save

You have the option to use `default`, `short`, `medium`, or `long` paths. `short` shows just the parent folder:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onlmldv1vn2x0hnm8mxg.png)

I find anything more than that to make the tabs way too large, but feel free to experiment.


## Adding links to the Rails error page

It would be really nice if the error page didn't just give us the file location, but instead created a link that would open the file in the code editor. We can actually modify the error page to do just that.

First, you'll need to find your Ruby installation. You can do that via `gem environment` (or `gem env`). This should give you something like the following:

```
RubyGems Environment:
  - RUBYGEMS VERSION: 3.4.10
  - RUBY VERSION: 3.2.2 (2023-03-30 patchlevel 53) [arm64-darwin22]
  - INSTALLATION DIRECTORY: /Users/michaeldaross/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0
  - USER INSTALLATION DIRECTORY: /Users/michaeldaross/.gem/ruby/3.2.0
  - RUBY EXECUTABLE: /Users/michaeldaross/.asdf/installs/ruby/3.2.2/bin/ruby
  - GIT EXECUTABLE: /usr/bin/git
  - EXECUTABLE DIRECTORY: /Users/michaeldaross/.asdf/installs/ruby/3.2.2/bin
  - SPEC CACHE DIRECTORY: /Users/michaeldaross/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /Users/michaeldaross/.asdf/installs/ruby/3.2.2/etc
  - RUBYGEMS PLATFORMS:
     - ruby
     - arm64-darwin-22
  - GEM PATHS:
     - /Users/michaeldaross/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0
     - /Users/michaeldaross/.gem/ruby/3.2.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => true
     - :bulk_threshold => 1000
     - "gem" => "--no-document"
  - REMOTE SOURCES:
     - https://rubygems.org/
 ...
```

Note the `GEM PATHS` line, which in my case points to `/Users/michaeldaross/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0`. If you navigate to that path in your filesystem, you should see a `gems` folder inside. This is where we'll find the files we need to edit.

Depending on your setup, you might have multiple versions of `actionpack` installed. To figure out which one your app is using, type

```bundle show | grep actionpack```

In my case, this gives

``` * actionpack (7.1.0)```

Once you know the folder, in your code editor, open up the error template: `gems/actionpack-7.1.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb`

Replace line 10:
```Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised:```

with

```Showing <a href="vscode://file/<%= @exception.file_name %>:<%= @exception.line_number %>"><i><%= @exception.file_name %></i></a> where line <b>#<%= @exception.line_number %></b> raised:```

This will change the line at the top of the error page into an actual link to open the relevant file in your code editor directly.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6sn6sgulvfwiw53jkigh.png)

If you’re not using VS Code, here are some other filesystem prefixes you can substitute:

- RubyMine: x-mine://open?file=
- MacVIM: mvim://open?url=file://
- Emacs: emacs://open?url=file://

Further extending this idea, let’s add links to the other files in the application stack trace.

In `gems/actionpack-7.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb`, add this line below line 21:

```| <a href="vscode://file/<%= Rails.root %>/<%= frame[:trace][0...frame[:trace].rindex(":")] %>">Code</a>```

This will add a code link to the right of each file in the  stack trace:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gui83jwaxe1eymdbkk2i.png)


## Bonus: Adding `rails-template-inspector`

[Rails Template Inspector](https://github.com/aki77/rails-template-inspector/tree/main) is an awesome debugging tool that allows you to hover over views in your application and see which file is rendering them, and then click to open the file in your code editor.

The repo includes installation instructions, but here are a few additional steps I took to make it more configurable for my team, some of whom use different IDEs or have different preferences.

in `config/environments/development.rb`, add the following:

```
 # Annotate rendered view with file names. Necessary for Rails Template Inspector tool.
  config.action_view.annotate_rendered_view_with_filenames = true

  # Options for the Rails Template Inpsector tool loaded in application.html.slim. You can override
  # these locally via environment variables.
  # -----------
  # @url_prefix: The string that launches your code editor from the browser. Options:
  # - Visual Studio Code: vscode://file
  # - RubyMine: x-mine://open?file=
  # - MacVIM: mvim://open?url=file://
  # - Emacs: emacs://open?url=file://
  # - IntelliJ: idea://open?file=
  # - PyCharm: pycharm://open?file=
  #
  #   Example: To use RubyMine, add the following line in .bashrc:
  #     export TEMPLATE_INSPECTOR_URL_PREFIX="x-mine://open?file="
  # -----------
  # @combo_key: The keyboard shortcut to launch the inspector
  # -----------
  # @no_auto_disable: Whether to automatically close the tool after taking you to your code editor
  config.template_inspector_options = {
    url_prefix: ENV["TEMPLATE_INSPECTOR_URL_PREFIX"] || "vscode://file",
    combo_key: ENV["TEMPLATE_INSPECTOR_COMBO_KEY"] || "command-shift-v",
    no_auto_disable: ENV["TEMPLATE_INSPECTOR_NO_AUTO_DISABLE"] || false,
  }
```

Then, to actually show the template inspector, you'll need to  include the `<rails-inspector>` web component tag to the page. Our app is using Slim templates, so for us we added the following to `application.html.slim`:

```
# Adds the Rails Template Inspector tool. See https://github.com/aki77/rails-template-inspector
- if Rails.env.development?
  script type="module" src="https://cdn.skypack.dev/@aki77/rails-template-inspector@^0.5.0"
  rails-inspector[
    root = "#{Rails.root}"
    url-prefix = Rails.configuration.template_inspector_options[:url_prefix]
    combo-key = Rails.configuration.template_inspector_options[:combo_key]
    no-auto-disable = Rails.configuration.template_inspector_options[:no_auto_disable]
  ]
```

Or, in ERB:
```
<% if Rails.env.development? %>
  <script type="module" src="https://cdn.skypack.dev/@aki77/rails-template-inspector@^0.5.0"></script>
  <rails-inspector 
  root="<%= Rails.root %>" 
  url-prefix="<%= Rails.configuration.template_inspector_options[:url_prefix] %>" 
  combo-key="<%= Rails.configuration.template_inspector_options[:combo_key] %>" 
  no-auto-disable = "<%= Rails.configuration.template_inspector_options[:no_auto_disable] %>">
</rails-inspector>

```

I hope this saves you some time and frustration. It certainly has for me!