Tips to level up your Ruby on Rails routing skills

Mastering Ruby on Rails routing is essential for any developer looking to build robust web applications efficiently. Whether you're a novice or a seasoned developer, enhancing your routing skills can significantly elevate your development process. 

Let me share with you in this article some invaluable tips to level up your Ruby on Rails routing expertise. From filtering routes effectively with grep to leveraging custom actions and understanding dynamic segments, and to exploring various techniques to streamline your routing workflow and maximize productivity. 

Enjoy the ride!

1. Pipe rails routes with grep

Filter out the noise by passing a keyword to the grep command line like so:

$ rails routes | grep users

Which lists only the lines containing the keyword.

   new_user_password GET      /users/password/new(.:format)   
  edit_user_password GET      /users/password/edit(.:format)       
       user_password PATCH    /users/password(.:format)                     
                     PUT      /users/password(.:format)                     
                     POST     /users/password(.:format)    
    new_user_session GET      /users/sign_in(.:format)       
        user_session POST     /users/sign_in(.:format)
destroy_user_session GET      /users/sign_out(.:format)

2. Add custom actions to your resources

Suppose you have a resource called articles, what happens if you nest actions such as print, download and publish?

  resources :articles do             
        get :print       
        get :download       
        post :publish   
  end

Notice how the param :article_id for the custom actions is inconsistent with RESTful actions param :id.

   article_print GET      /articles/:article_id/print(.:format)
article_download GET      /articles/:article_id/download(.:format)
 article_publish POST     /articles/:article_id/publish(.:format)  
        articles GET      /articles(.:format)
                 POST     /articles(.:format)
     new_article GET      /articles/new(.:format)
     edit_article GET     /articles/:id/edit(.:format)
         article GET      /articles/:id(.:format)
                 PATCH    /articles/:id(.:format)
                 PUT      /articles/:id(.:format)
                 DELETE   /articles/:id(.:format)
     

This is not ideal because you will need to write separate callbacks to load the record for each key param in your controller.

class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :des   
  before_action :set_article2, only: [:print, :download, :publis   
  
  # ...   
  def set_article() = @article = Article.find(params[:id])   
  def set_article2() = @article = Article.find params[:article_i 
end

2.1 Dynamic Segments

Bound Parameters and Dynamic segments may yield exactly what you need. It's also easy to understand.

resources :articles do     
  collection do
      get ':id/print', to: 'articles#print'       
      get ':id/download', to: 'articles#download'       
      post ':id/publish', to: 'articles#publish'    
  end   
end

But this won't generate routing aliases, losing URL helpers.

GET      /articles/:id/print(.:format)
GET      /articles/:id/download(.:format)
POST     /articles/:id/publish(.:format)

2.2 Member Routes

By nesting under member routes, we retain consistent key params.

resources :articles do
    member do
      get :print
      get :download
      post :publish
    end
  end

While also retaining URL helpers.

   print_article GET      /articles/:id/print(.:format)
download_article GET      /articles/:id/download(.:format)
 publish_article POST     /articles/:id/publish(.:format)

3. Polymorphic URL helpers

This only works with aliased resource actions. You can shorten a link_to argument.

link_to "Download Article", download_article_path(@article)

By enclosing record with the action Symbol in an Array:

link_to "Download Article", [:download, @article]

As you dive deeper into implementing these advanced routing techniques in your Ruby on Rails projects, remember: mastery is a journey filled with practice and experimentation.

Each tip shared here brings a fresh perspective to optimizing your routing structure, offering the flexibility and efficiency required to conquer even the most complex application challenges. By weaving these strategies into your development workflow, you'll not only elevate the maintainability and scalability of your codebase but also empower yourself to navigate the intricate web of routes with confidence. 

Thank you for taking the time to read my article. If you are interested in learning more about me we can connect with each other.‍

If you're curious to know more about Montani International Inc please feel free to explore our various online platforms and be sure to check out some of our informative articles, latest project updates, and behind-the-scenes glimpses of what it's like to work at Montani.