Sneaky Rails Magic

Ruby on Rails is wonderful. After all, it’s maximized for developer happiness. I won’t waste your time preaching about the simplicity, design, and conventions that make it easy hit the ground running in a new codebase.

Magician For all of its ease, there’s always some sneaky Rails Magic lurking in the recesses that can stump those new to the underlying syntactic sugar.

Routing?

I thought I understood routing.
Highway at Night Define a scope in your routes.rb file.

Provide a URL and controller action.

I could even add a route helper to make routing easier within controllers and views.

If I was getting really carried away, I could leverage resources, which would make my routes file even more readable and concise. But that’s another topic for another day.

Background

In my last role, I’d often encounter routes that made use of scope but did not leverage resources. This was in large part because our infrastructure utilized a middle layer to make database requests, so controllers did not often necessitate create, edit, patch, or delete actions.

It wouldn’t be out-of-the-ordinary to encounter a route that was structured like this:

scope '/foo' do
  get '/bar' => 'qux#index', as: :foo_bar
  get '/baz' => 'qux#create', as: :foo_baz
end

As you may already know, in the example above, foo_bar and foo_baz are route helpers that allow you to reference the route path in a view or controller by simply referencing the route helper, like:

foo_bar_path

Route helpers are relevant to this story because I was working on a task that required me to update route helpers in a several views but first I wanted to visit the URLs locally before making the changes.

Route Helper Magic

While I was checking the routes.rb file to find the URLs of the pages I wanted to view locally, I noted the relevant routes listed looked like this:

scope 'foo' as: 'foo' do
  get '/baz' => 'qux#index', as: :baz
end

My previous understanding of routes, told me to look for baz_path in the codebase, but all I could not find an exact match, which was strange.

In the codebase, however, I did see a route helper named:

foo_baz_path

Was foo_baz_path the correct path?

Where was baz_path?

Resolution

To get a definitive answer, I knew it was time to run rake routes.

For those new to Rails, rake routes is a common practice done during development to verify that your routes are set up correctly. This will also show the appropriate route helpers to use in your code.

So, I ran rake routes and noted the following:

Prefix Verb-foo_baz
URI Pattern-GET /foo/baz(.:format)
Controller Action-qux#index

Aha! There it was, foo_baz. Prefix, here, refers to the route helper name.

So the route helper did exist, as foo_baz_path.

Explanation

Let’s look back at the original code:

scope 'foo' as: 'foo' do
  get '/baz' => 'qux#index', as: :baz
end

Here, we can conclude the following:

as: ‘foo’ is adding a prefix to the names of all route helpers defined within this scope.

Without as: ‘foo’, the route helper would just be baz_path

With as: ‘foo’, it becomes foo_baz_path.

Conclusion

Whether you’re new to Rails or have been building in it for years, understanding Rails’ “Convention over Configuration” will pay dividends.

No matter if you’re working in a new codebase or building a greenfield app, Rails Magic is something to know, and know well. There are many more examples of Rails Magic in Routing. Check out the guides and see for yourself!