Route Rollercoaster
Written on May 22, 2025

When learning Rails, routes are one of the most puzzling things I’ve encountered so far. Probably any person who knows how to properly use the framework will see this as stupid, but from where I stand, and how I’ve learned it in Codecademy, things were full of exceptions and I couldn’t understand what was what. So a couple of days ago, I decided to read the routes documentation (https://guides.rubyonrails.org/routing.html ). Admittedly, I could only get through 25% of the whole document and realized that this is a big topic.
Basically, what I understood at first is that when I have something like:
```
get "welcome", to: "welcome#index"
```
I was ‘getting’ the request of going to the welcome page and taking you to the `index.html.erb`…
In my head, it made sense. After all, you are ‘getting something’ to ‘somewhere’ :)
After having many routing errors and only being able to make them work by ‘shotgunning’ random name orders at the routes, I had a good session with the LLM to break every part down.
Clearly, I had it all backwards. `get` is not getting me anything but taking me somewhere, and `to:` is not taking me somewhere but ‘getting’ a controller.
If I’ve understood it correctly, the structure is basically:
* `get "welcome"` == `mydomain/welcome/`
* `to: "welcome#index"` == (inside my `PagesController`, or whichever controller we are referring to) take the `def index` method and apply whatever is inside (if it’s empty and it’s a RESTful method, it will probably do what’s predefined)
After understanding these two blocks, it was much easier for me to do very simple static navigation pages or apply any custom method for whatever logic we wanted to use.
---
Then I came across having to deal with dynamic values such as `:id` or `:category` when building the learning cards experiment. Suddenly, there were two new things in my route.
I no longer had a simple folder structure for the `get`, but also had to deal with a thing with a semicolon in it.
Example:
```
get "theory/category/:category", to: "theory#start", as: "theory_start"
```
What was `:category`? Certainly none of the folders I had. I was a bit confused and couldn’t really get it. Same goes for the `, as: "theory_start"` part. No idea what these were for.
After more digging, the explanation I got kind of made sense. (Kind of sense not because the logic behind it isn’t good, that I don’t know, but because I only understand 60% of it...)
From what I’ve understood so far, the `:value` is used to pass dynamic values. In my case, I had two situations where I needed to use these: the `Card.id` and the `Card.category`, which were changing constantly in the routes since we were not manually hardcoding those routes for all the available IDs nor the categories.
How to correctly route and call them is still something I’ll need to practice more, but at least I understand why these are so different from the static ones.
Regarding the `, as: "helper_name"` section, well… I do understand this is the name I want to give the route helper in order to call it.
What I first thought is that you can use it as follows:
```
get "theory/category/:category", to: "theory#start", as: "theory_start"
```
We basically can call it just by using `theory_start_path[:category]` instead of `theory/category[:category]`
Which was not correct and gave me route errors. We need to use the function grammar, since apparently, these helpers are functions.
So basically:
```
theory_start_path(category: "category_id")
```
I’ll need to practice these more, and I probably should do a couple more experiments where I need to rely more heavily on passing dynamic values.
---
My last surprise when it comes to routes was the encounter I had this morning. I’m still trying to unpack this altogether, but apparently, there are two ways (that I know of at this point) of defining routes:
```
namespace :projects do
get "hacker", to: "hacker#index"
end
```
and to my surprise:
```
namespace :projects do
resources :hacker, only: [:index]
end
```
This is how my original routes were looking:
```
# Routes for projects
resources :projects, only: [:index, :create, :edit, :destroy]
namespace :projects do
# hacker experiment routes
get "hacker", to: "hacker#index"
post "hacker/compare", to: "hacker#compare"
post "hacker/reset", to: "hacker#reset"
# word experiment routes
get "wordplay", to: "wordplay#index"
# this helps us fetch any post input done inside of wordplay and handle it with transform
post "wordplay/transform", to: "wordplay#transform"
# questionnaire about rails routes
get "theory/category/:category", to: "theory#start", as: "theory_start"
get "theory", to: "theory#index"
get "theory/question/:id", to: "theory#show", as: "theory_question"
post "theory/question/:id/answer", to: "theory#answer", as: "theory_answer"
get "theory/results", to: "theory#results", as: "theory_results"
get "theory/questions/grouped_questions", to: "theory/questions#grouped_questions", as: :grouped_questions
resources :questions, controller: "theory/questions"
end
```
Which, after digging into the grammar, I ended up refactoring to:
```
namespace :projects do
resources :hacker, only: [:index] do
collection do
post :reset
post :compare
end
end
resources :wordplay, only: [:index] do
collection do
post :transform
end
end
resources :theory, only: [:index, :show] do
collection do
get :start
post :answer
get :results
get :grouped_questions
end
member do
get :question
end
end
end
```
My learnings through doing this mini refactor were that inside the `only: []` part, you can only (only!) place RESTful methods. (Which I don’t know yet by heart, but `index`, `delete`, and others I should memorize ASAP.) In my case, I was mainly using `index` and `show` for the projects section of the website.
The other part that I more or less remember is that—for my current limited knowledge—there are two types of controller functions I could need to set up in this way of doing the routes: `collection` and `member`.
From what I understood, `member` handles a single item with a specific ID, and `collection` gives you an array (maybe).
So if I’m dealing with anything that doesn’t need to pass a specific ID, we use `collection`.
---
Clearly, if you’ve read through all of this, you can see I’m still trying to solidify these concepts.
The only reason why I’ve decided to write this down is because it’s forcing me to put what’s all wibbly-wobbly in my head into specifics, helping me identify that it was not as ‘understood’ as I thought it was.
After all of this, I think I know the reason why when I introduced a dropdown menu to manually switch between English, German, and Spanish in my `mientrenadorpersonal.com` website, the LLM wanted me to manually rename all the places where I was calling links to or buttons to, because all the routes would break after switching languages.
If I was implementing the locale swapper with ‘hardcoded’ routes and this would insert `/de/` or `/es/` into the `/en/` route, it probably would be responsible for these breaks.
If this is the case, it means there should be an ‘easy’ solution by refactoring the routes instead of needing to hunt around all the views for locations where these were incorrectly called… or, now that I think of it, I’ll probably have to do both anyway…
I guess it’s time for me to dig into Vim shortcuts for VS Code to make my life a bit easier finding references… (which probably is not even what I need, but a link tree of some sort).
---
Anyways… most likely, everything I wrote here is about 50% wrong. If that’s the case, you’re welcome for the laughs.