Building A Visitor Tracker with Rails
Tags: ruby, rails
Published: 2023-12-03 23:05:12

---
title: Building A Visitor Tracker with Rails
published: true
date: 2023-11-20 23:20:28 UTC
tags: #ruby #rails
canonical_url: https://carlosmv.hashnode.dev/building-a-visitor-tracker-with-rails
---

In this article, we are going to build a visitor tracker app using Rails. The app will intercept the requests and show information like the client's IP, URL, path, and request method.

### Requirements

- Ruby installed

- Rails installed

### Creating a new Rails project.

First, we need to create a new rails project.

```
rails new visitor-tracker

```

### Creating the model, database, controllers, and routes.

```
rails g resource tracker

```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699829832992/74a56e89-ca26-4bab-910a-64a3c5d0bde3.png)

We go to `db/migrate/<timestamp>create_trackers.rb` to define the attributes of the `tracker` table. There will be eight attributes: IP address, request URL, port, path, method, browser, OS, time and the service name.

```
class CreateTrackers < ActiveRecord::Migration[7.0]
  def change
    create_table :trackers do |t|

      t.timestamps
      t.string :ip_address
      t.string :request_url
      t.integer :request_port
      t.string :request_path
      t.string :request_method
      t.string :browser_type
      t.datetime :request_time
    end
  end
end

```

We run the following command in our terminal, to migrate the table:

```
rails db:migrate

```

We go to `app/controllers/tracker_controller.rb` and create the functions to retrieve all the entries in the database, and to store the request info in the database.

**Index**

```
  def index
        @trackers = Tracker.all
        render json: @trackers
    end

```

#### **Show**

```
 def show
        @tracker = Tracker.find(params[:id])
        render json: @tracker
    end

```

**Create**

```
   def create
        @tracker = Tracker.create(
            ip_address: params[:ip_address],
            request_url: params[:request_url],
            request_port: params[:request_port],
            request_path: params[:request_path],
            request_method: params[:request_method],
            browser_type: params[:browser_type],
            request_time: params[:request_time],

        )
        render json: @tracker
    end

```

**Complete** `trackers_controllers.rb` **file.**

```
class TrackersController < ApplicationController
    def index
        @trackers = Tracker.all
        render json: @trackers
    end

    def show
        @tracker = Tracker.find(params[:id])
        render json: @tracker
    end

    def create
        @tracker = Tracker.create(
            ip_address: params[:ip_address],
            request_url: params[:request_url],
            request_port: params[:request_port],
            request_path: params[:request_path],
            request_method: params[:request_method],
            browser_type: params[:browser_type],
            request_time: params[:request_time],

        )
        render json: @tracker
    end    
end

```

In `db/seed.rb` we created a record to display when we make the GET request.

```
tracker_1 = Tracker.create(ip_address: "127.0.0.1", 
request_url: 'http://localhost:8000', request_port: 8000, request_path: "/",
request_method: "GET")

```

Then we run the following command to apply the changes.

```
rails db:seed

```

Now, let's start our server and see if it can show the data.

```
rails server

```

We navigate to `localhost:port/trackers` and we should see the following response in the browser or HTTP client:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699833595165/e8e99a10-7217-4c9f-bb0e-d8db897811f2.png)

### Adding a middleware

We create a new folder, `lib/middleware` and create the `lib/middleware/visitor_tracker` file.

```
module Middleware
    class VisitorTracker
      def initialize(app)
        @app = app

      end

      def call(env)
        request = ActionDispatch::Request.new(env)

        Tracker.create(ip_address: request.ip, 
        request_url: request.original_url, request_port: request.port, request_path: request.path,
        request_method: request.request_method)

        @app.call(env)
      end
    end  
end

```

Here, we create our middleware, create the `VisitorTracker` class and create two methods, initialize and call.

In the call method, we create an instance of the `ActionDispatch::Request` class and then, create a new record in the database with the request information every time the middleware is executed.

Then, we go to `config/application.rb` file to declare our middleware.

```
require_relative "boot"
require_relative "../lib/middleware/visitor_tracker"

require "rails/all"

Bundler.require(*Rails.groups)

module Visitor
  class Application < Rails::Application

    config.load_defaults 7.0
    config.middleware.use Middleware::VisitorTracker

  end
end

```

Here we use the `config.middleware.use` method and pass the Middleware module and the `VisitorTracker` class. Rails will execute this middleware just before your application is called.

Now, to create a full-stack app, we need to go to `config/routes.rb` and paste the following code.

```
Rails.application.routes.draw do
  resources :trackers

  root "trackers#index"
  get "/trackers", to: "trackers#index"
end

```

Then, we need to go to the `app/controllers/trackers_controllers.rb` file and remove the code `render json: @trackers` from the index function. It should look like this:

```
def index
        @trackers = Tracker.all

end

```

Next, we go to the `app/views/trackers` folder and create the `app/views/trackers/index.html.erb` file.

```
<!DOCTYPE html>
<html>
    <head>
        <title>Visitor Tracker</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>

        <%= stylesheet_link_tag "index", "data-turbo-track": "reload" %>
        <%= javascript_importmap_tags %>
    </head>
    <h1>Visitor Tracker</h1>
    <table>
        <tr>
            <th>IP Address </th>              
            <th>Request URL </th>                     
            <th>Request Port </th>  
            <th>Request Path </th>  
            <th>Request Method </th>

        </tr>
        <% @trackers.each do |tracker| %>
        <tr>
            <td><%= tracker.ip_address %></td>         
            <td><%= tracker.request_url %></td>     
            <td><%= tracker.request_port %></td>
            <td><%= tracker.request_path %></td>
            <td><%= tracker.request_method %></td>

        </tr>
        <% end %>
    </table>

</html>

```

We navigate to `localhost:port/` and we should see the following response in the browser or HTTP client:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699838535574/6ca0e3a1-04cd-4ec0-9ce7-d1c6aa7f3e1d.png)

Next, we create the `app/assets/stylesheets/index.css` file and paste the following code.

```

table {
    border-collapse: collapse;
    margin-bottom: 1rem;
  }

  th,
  td {
    padding: 0.5rem;
    border: 1px solid #ccc;
  }

  th {
    text-align: left;
  }

  td {
    text-align: left;
  }

  .column-gap-10 {
    column-gap: 10px;
  }

```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700427730809/4dc708ed-3a8e-4cce-a7a7-f77559ba4467.png)

### Conclusion

In this article, we learned about how to build a visitor tracker with Rails and how to create custom middleware. With this app, we can see the activity of our applications.

The source code is [here](https://github.com/carlosm27/rails-visitor-tracker).

Thank you for taking the time to read this article.

If you have any recommendations about other packages, architectures, how to improve my code, my English, or anything; please leave a comment or contact me through [**Twitter**](https://twitter.com/Carlos_marcv), or [**LinkedIn**](https://www.linkedin.com/in/carlos-marcano-a2135a134/).

### Resources

[Getting Started with Rails](https://guides.rubyonrails.org/getting_started.html)

[Using Rails and HTML to View, Sort, and Search Tables.](https://medium.com/swlh/using-rails-and-html-to-view-sort-and-search-tables-fbf8a0543558)

[Rails Middleware: (Almost) Everything You Need to Know](https://www.writesoftwarewell.com/rails-middleware-what-why-and-how/#lets-add-custom-middleware-in-rails)