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 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:
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:
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; } 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.
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, or LinkedIn.




Top comments (0)