Mastering Rails Web Navigation with link_to and button_to Helpers - Part 1
Tags: rails, ruby, webdev, tutorial
Published: 2023-10-19 19:01:50

**Note:** This tutorial is divided into two parts. In Part 1 **(you are reading)**, we'll explore the Rails web navigation system, understand how Rails handles requests, and delve deep into the world of middleware. In Part 2, we'll focus on mastering the `link_to` and `button_to` helpers and address frequently asked questions.

Great, let’s get started!

**TABLE OF CONTENTS (Part 1)**

[Introduction](#introduction)

[Navigation System](#navigation-system)

[How Rails Handles Requests](#how-rails-handles-requests)

[Middlewares in Rails](#middlewares-in-rails)

[Frequently Asked Questions](#frequently-asked-questions)

#Introduction

Have you ever wondered what happens when a user sends a web request to a site like [Rails](https://rubyonrails.org/) and waits for a response?




Imagine a scenario where a user clicks on a link or button on the [Rails](https://rubyonrails.org/) website. This simple action initiates a [web request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) from the user's browser, which then travels through the vast universe of inter-webs galaxies to land on the planet web server that hosts "[Rails](https://rubyonrails.org/)". The server then does its best and processes the request that was just received and sends back a response with the needed information and lands it safely to the plant user's browser, all in the blink of an eye!

It's plain to see from that fancy figure up top that Rails has a pretty sophisticated communication process for handling incoming browser requests and dispatching responses. The process involves two major components: [ActionController](https://guides.rubyonrails.org/action_controller_overview.html) and [ActionView](https://guides.rubyonrails.org/action_view_overview.html).

The **ActionController** is where it's when it comes to the app's logic and data. It's the one in charge of talking to the database and carrying out CRUD operations as defined in the controller files. Meanwhile, **ActionViews** is all about the presentation layer and cooking up the right response for each web request. This rockstar is responsible for putting together that response by rendering HTML templates, which are a mix of embedded Ruby code and HTML tags.

In the world of Rails, magic is not a concept found in books and movies. It's part of the Rails framework! This magic simplifies the process of creating views, eliminates messy and duplicated code, and provides many other benefits that make our lives as developers easier and happier. But wait, how does it work, you might ask? By providing reusable helper classes and modules that encapsulate common behaviours and functionalities.

Each helper class includes a library of helper methods that can be used to generate HTML tags and other content in views. For instance, the [FormHelper](https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html) includes "form_for", the [UrlHelper](https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html) features the famous "link_to" and "button_to", and the [TextHelper](https://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html) provides "truncate" among others. When we developers use these helpers, we can create more maintainable and organized code for our web applications. It's like having a wizard's wand in our hands!

That being said, now hold on tight, everyone! We're about to dive into the thrilling world of web navigation with the help of two giants of the Rails world: `link_to` and `button_to`, both of which belong to the legendary UrlHelper module. These powerhouses are the masterminds behind link creation and URL retrieval based on Rails routes. Join us on this adventure, and you'll be a web navigation master in the blink of an eye!

#Navigation System

Welcome to the web navigation systems of Rails. As we traverse the digital landscape, two guiding stars, `link_to` and `button_to`, light our path. These methods are pivotal in Rails, enabling seamless navigation. But to truly appreciate their magic, we must first understand the underlying processes of Rails, especially the role of middleware and their responsibility in processing a web request.

#How Rails Handles Requests

Let me set the scene for you. Imagine the web as a vast cosmos. Each click or request is like a spaceship ([thinking of USS Enterprise, any Star Trek fans!](https://en.wikipedia.org/wiki/USS_Enterprise_(NCC-1701-D))) embarking on an interstellar journey. When you navigate platforms like Rails, you're setting a course through the Rails galaxy. To show you a glimpse of this voyage, Engage:

Navigating the vast universe of the web is akin to embarking on an interstellar journey. Each click, each request, is a spaceship travelling from one celestial body to another, seeking information. Let's chart the course of this spaceship as it journeys through the Rails galaxy as described in the outstanding figure above:

1. **Liftoff:** The user, our astronaut, launches their spaceship by entering a URL in their browser, like [https://rubyonrails.org/](https://rubyonrails.org/).

2. **First Contact:** This spaceship, now carrying **a HTTP request**, approaches the Rails galaxy and makes its first contact with the **Rails Router** (config/routes.rb).

3. **Guidance System:** The router, acting as the galaxy's guidance system, determines which controller action should be activated — be it index, new, edit, show, or destroy.

4. **Data Mining:** The controller, now in charge, communicates with the appropriate model methods to gather the necessary resources.

5. **Database Planet:** The model descends onto the Database planet to fetch the required data, which is then sent back to the controller.

6. **Crafting the Message:** The controller, having gathered all it needs, communicates with the view to craft the final message.

7. **Transmission:** The view, using a mix of HTML and embedded Ruby, prepares the final response and sends it back to the waiting spaceship.

8. Safe Return: The spaceship, now with the response, travels back and lands safely on the user's (our astronaut) browser, displaying the information. Missions accomplished!

This celestial dance ensures that each user's request is processed with precision. Central to this are ActionController and ActionView. While the ActionController orchestrates the logic and data, ActionViews crafts the visual spectacle, presenting the perfect response.

The magic of Rails isn't mere folklore; it's tangible. It simplifies view creation, minimizes redundant code, and offers numerous benefits. This enchantment is powered by helper classes and modules that encapsulate common behaviours and functionalities, acting as our cosmic tools, and guiding us through the Rails universe.

#Middlewares in Rails

###Navigating the Middleware Nebula:

In the vast cosmos of a Rails application, middlewares are like the guiding stars in a nebula. Each middleware, similar to a star, has its unique luminance, ensuring that the web request travels smoothly through the Rails galaxy.

###Understanding Middlewares:

Middleware in Rails is middleware in Rack. They act as the checkpoints or space stations between the web server (like Puma or Unicorn) and the Rails mothership. They inspect, modify, or process incoming and outgoing space signals (requests and responses). Each middleware either acts on the signal or hands it over to the next station (middleware) in the sequence, ensuring a smooth interstellar communication flow.

###Middleware in Action: A Real-World Scenario

Imagine a scenario where you want to log the time taken for each space signal (request) in your Rails application. Instead of embedding this logic in every corner of your mothership (Rails application controller), a middleware can elegantly handle it, centralizing the process and ensuring efficient communication.

```ruby
class RequestTimerMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    start_time = Time.now
    status, headers, response = @app.call(env)
    end_time = Time.now

    Rails.logger.info "Request took #{end_time - start_time} seconds."

    [status, headers, response]
  end
end
```

In this example, the RequestTimerMiddleware logs the time taken for each request. The initialize method stores the current application, and the call method calculates the time difference between the start and end of the request.

###How to Add a Middleware to Rails:

To add the above middleware to your Rails application, you'd update the `config/application.rb` file:

```ruby
config.middleware.use RequestTimerMiddleware
```

###Common Middlewares in Rails:

Rails comes with a set of built-in middlewares that handle various tasks:

- `Rack::Sendfile`: Handles sending files efficiently from the server.
- `ActionDispatch::Static`: Serves static files from the public directory.
- `Rack::Logger`: Logs incoming HTTP requests.
- `Rack::Runtime`: Sets an "X-Runtime" response header, indicating the response time of the request.
- `ActionDispatch::Cookies`: Manages cookies, both reading and writing.
- `ActionDispatch::Session::CookieStore`: Handles cookie-based session storage.

... and many more! You can list that middleware by running `./bin/rails middleware`. For a new Rails 7 application it looks like this:

```ruby
use ActionDispatch::HostAuthorization
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActionDispatch::ServerTiming
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use Sentry::Rails::CaptureExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use Sentry::Rails::RescuedExceptionInterceptor
use ActionDispatch::ActionableExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use ActionDispatch::PermissionsPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
use ActionDispatch::Static
run MyApp::Application.routes
```

Middleware, while often operating behind the scenes, are the unsung heroes of a Rails application. They meticulously shape the request-response lifecycle, ensuring each signal is processed with precision. As we venture deeper into Rails, remember that for every task, be it logging, authentication, or session management, there's likely a middleware guiding the way. Now, let's set our sights on the next celestial wonders: `link_to` and `button_to`.

#Frequently Asked Questions

**1. What is Middleware in Rails?**

Middleware is a layer in the Rails stack that sits between the web server and the Rails application. It processes requests before they reach the application and can also modify the response before it's sent back to the client. Middleware components are used for a variety of tasks, such as logging, caching, and security.

**2. How do I add a new Middleware to my Rails application?**

You can add a new middleware to your Rails application by using the `config.middleware.use` method in the `config/application.rb file`. For example:

```ruby
config.middleware.use CustomMiddleware
```

**3. How do I remove or skip a Middleware in Rails?**

If you want to remove or skip a middleware, you can use the `config.middleware.delete` method in the `config/application.rb` file. For example:

```ruby
config.middleware.delete Rack::Lock
```

**4. How can I view the list of Middlewares used in my Rails 7 application?**

You can view the list of middlewares used in your Rails application by running the command `./bin/rails middleware` in the terminal. This will display the middleware stack in the order they are executed.

**5. Why is the order of Middlewares important in Rails?**

The order of middleware is crucial because they are executed in a top-down sequence as they appear in the middleware stack. If one middleware stops the request from propagating down the stack, subsequent middleware won't get executed. Therefore, it's essential to ensure that the middleware are in the correct order, especially when they depend on each other.

Coming Up in **Part 2**: Dive deep into the functionalities of `link_to` and `button_to`, two powerful helpers that make web navigation in Rails a breeze. We'll explore their syntax, usage, and advanced features. Plus, we'll address some frequently asked questions to ensure you're well-equipped to navigate the Rails universe. Stay tuned!