[Awesome Ruby Gem] Use ahoy_matey gem to track visits and events in Ruby, JavaScript, and native apps

ahoy_matey

πŸ”₯ Simple, powerful, first-party analytics for Rails.

Track visits and events in Ruby, JavaScript, and native apps. Data is stored in your database by default, and you can customize it for any data store as you grow.

Installation

You can install it as a gem:

1
$ gem install ahoy_matey

or add it into a Gemfile (Bundler):

1
2
3
4
5
# Gemfile

# ankane/ahoy: Simple, powerful, first-party analytics for Rails
# https://github.com/ankane/ahoy
gem 'ahoy_matey', '3.2.0'

Migration

Generate and run migraions:

1
2
3
$ rails generate ahoy:install

$ rails db:migrate

Usages

Restart your web server, open a page in your browser, and a visit will be created πŸŽ‰

Track your first event from a Rails controller with:

1
ahoy.track "My first event", language: "Ruby"

JavaScript, Native Apps, & AMP

Enable the API in config/initializers/ahoy.rb:

1
Ahoy.api = true

And restart your web server.

JavaScript

For Rails 6 / Webpacker, run:

1
$ yarn add ahoy.js

And add to app/javascript/packs/application.js:

1
import ahoy from "ahoy.js";

Track an event with:

1
ahoy.track("My second event", {language: "JavaScript"});

Native Apps

Check out Ahoy iOS - https://github.com/namolnad/ahoy-ios and Ahoy Android - https://github.com/instacart/ahoy-android.

How It Works

Visits

When someone visits your website, Ahoy creates a visit with lots of useful information.

  • traffic source - referrer, referring domain, landing page

  • location - country, region, city, latitude, longitude

  • technology - browser, OS, device type

  • utm parameters - source, medium, term, content, campaign

  • Use the current_visit method to access it.

Prevent certain Rails actions from creating visits with:

1
skip_before_action :track_ahoy_visit

This is typically useful for APIs. If your entire Rails app is an API, you can use:

1
Ahoy.api_only = true

You can also defer visit tracking to JavaScript. This is useful for preventing bots (that aren’t detected by their user agent) and users with cookies disabled from creating a new visit on each request. :when_needed will create visits server-side only when needed by events, and false will disable server-side creation completely, discarding events without a visit.

1
Ahoy.server_side_visits = :when_needed

Events

Each event has a name and properties. There are several ways to track events.

Ruby
1
ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"

Track actions automatically with:

1
2
3
4
5
6
7
8
9
class ApplicationController < ActionController::Base
after_action :track_action

protected

def track_action
ahoy.track "Ran action", request.path_parameters
end
end
JavaScript
1
ahoy.track("Viewed book", {title: "The World is Flat"});

Track events automatically with:

1
ahoy.trackAll();

See Ahoy.js - https://github.com/ankane/ahoy.js for a complete list of features.

Native Apps

See the docs for Ahoy iOS - https://github.com/namolnad/ahoy-ios and Ahoy Android - https://github.com/instacart/ahoy-android.

Associated Models

Say we want to associate orders with visits. Just add visitable to the model.

1
2
3
class Order < ApplicationRecord
visitable :ahoy_visit
end

When a visitor places an order, the ahoy_visit_id column is automatically set πŸŽ‰

See where orders are coming from with simple joins:

1
2
3
Order.joins(:ahoy_visit).group("referring_domain").count
Order.joins(:ahoy_visit).group("city").count
Order.joins(:ahoy_visit).group("device_type").count

Here’s what the migration to add the ahoy_visit_id column should look like:

1
2
3
4
5
class AddVisitIdToOrders < ActiveRecord::Migration[6.1]
def change
add_column :orders, :ahoy_visit_id, :bigint
end
end

Customize the column with:

1
visitable :sign_up_visit

Users

Ahoy automatically attaches the current_user to the visit. With Devise, it attaches the user even if they sign in after the visit starts.

With other authentication frameworks, add this to the end of your sign in method:

1
ahoy.authenticate(user)

To see the visits for a given user, create an association:

1
2
3
class User < ApplicationRecord
has_many :visits, class_name: "Ahoy::Visit"
end

And use:

1
User.find(123).visits
Custom User Method

Use a method besides current_user

1
Ahoy.user_method = :true_user

or use a proc

1
Ahoy.user_method = ->(controller) { controller.true_user }
Doorkeeper

To attach the user with Doorkeeper, be sure you have a current_resource_owner method in ApplicationController.

1
2
3
4
5
6
7
class ApplicationController < ActionController::Base
private

def current_resource_owner
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
end
end

Exclusions

Bots are excluded from tracking by default. To include them, use:

1
Ahoy.track_bots = true

Add your own rules with:

1
2
3
Ahoy.exclude_method = lambda do |controller, request|
request.ip == "192.168.1.1"
end

See ankane/ahoy: Simple, powerful, first-party analytics for Rails - https://github.com/ankane/ahoy to learn more Usages.

References

[1] ankane/ahoy: Simple, powerful, first-party analytics for Rails - https://github.com/ankane/ahoy

[2] ahoy_matey | RubyGems.org | your community gem host - https://rubygems.org/gems/ahoy_matey

[3] Tracking Events with Ahoy | Drifting Ruby - https://www.driftingruby.com/episodes/tracking-events-with-ahoy

[4] namolnad/ahoy-ios: Analytics and attribution library for Apple platforms built on top of Ahoy for Ruby on Rails. - https://github.com/namolnad/ahoy-ios

[5] instacart/ahoy-android: Android attribution library build on top of Ahoy for Ruby on Rails. - https://github.com/instacart/ahoy-android

[6] ankane/ahoy.js: Simple, powerful JavaScript analytics - https://github.com/ankane/ahoy.js