Repository URL to install this package:
|
Version:
1.2.1.ayni.2 ▾
|
| app |
| config |
| lib |
| test |
| vendor |
| .gitignore |
| CHANGELOG.md |
| Gemfile |
| LICENSE.txt |
| README.md |
| Rakefile |
| ahoy_matey.gemspec |
:fire: Never build an analytics platform from scratch again.
Ahoy provides a solid foundation to track visits and events in Ruby, JavaScript, and native apps.
Works with any data store so you can easily scale.
:tangerine: Battle-tested at Instacart
:postbox: To track emails, check out Ahoy Email.
See upgrade instructions on how to move to 1.0.
Add this line to your application’s Gemfile:
gem 'ahoy_matey'
And add the javascript file in app/assets/javascripts/application.js after jQuery.
//= require jquery //= require ahoy
Ahoy supports a number of data stores out of the box. You can start with one of them and customize as needed, or create your own store from scratch.
For Rails 4 and PostgreSQL 9.4 or greater, use:
rails generate ahoy:stores:active_record -d postgresql-jsonb rake db:migrate
For Rails 4 and PostgreSQL 9.2 and 9.3, use:
rails generate ahoy:stores:active_record -d postgresql rake db:migrate
Otherwise, follow the instructions for MySQL.
Add activeuuid to your Gemfile.
gem 'activeuuid', '>= 0.5.0'
And run:
rails generate ahoy:stores:active_record rake db:migrate
If you just want visits, run:
rails generate ahoy:stores:active_record_visits rake db:migrate
rails generate ahoy:stores:mongoid
Add fluent-logger to your Gemfile.
gem 'fluent-logger'
And run:
rails generate ahoy:stores:fluentd
Use ENV["FLUENTD_HOST"] and ENV["FLUENTD_PORT"] to configure.
rails generate ahoy:stores:log
This logs visits to log/visits.log and events to log/events.log.
rails generate ahoy:stores:custom
This creates a class for you to fill out.
class Ahoy::Store < Ahoy::Stores::BaseStore def track_visit(options) end def track_event(name, properties, options) end end
See the ActiveRecordStore for an example.
When someone visits your website, Ahoy creates a visit with lots of useful information.
Use the current_visit method to access it.
Each event has a name and properties.
There are three ways to track events.
ahoy.track("Viewed book", {title: "The World is Flat"});
or track events automatically with:
ahoy.trackAll();
See Ahoy.js for a complete list of features.
ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"
See the HTTP spec until libraries are built.
Ahoy automatically attaches the current_user to the visit.
With Devise, it will attach the user even if he or she signs in after the visit starts.
With other authentication frameworks, add this to the end of your sign in method:
ahoy.authenticate(user)
Stores are built to be highly customizable.
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore # add methods here end
Exclude visits and events from being tracked with:
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore def exclude? bot? || request.ip == "192.168.1.1" end end
Bots are excluded by default.
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore def track_visit(options) super do |visit| visit.gclid = visit_properties.landing_params["gclid"] end end def track_event(name, properties, options) super do |event| event.ip = request.ip end end end
If you use a method other than current_user, set it here:
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore def user controller.true_user end end
Exceptions are rescued so analytics do not break your app.
Ahoy uses Errbase to try to report them to a service by default.
To customize this, use:
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore def report_exception(e) Rollbar.report_exception(e) end end
For ActiveRecord and Mongoid stores
class Ahoy::Store < Ahoy::Stores::ActiveRecordStore def visit_model CustomVisit end def event_model CustomEvent end end
Page views
ahoy.trackView();
Clicks
ahoy.trackClicks();
Rails actions
class ApplicationController < ActionController::Base after_filter :track_action protected def track_action ahoy.track "Processed #{controller_name}##{action_name}", request.filtered_parameters end end
To track visits across multiple subdomains, use:
Ahoy.cookie_domain = :all
By default, a new visit is created after 4 hours of inactivity.
Change this with:
Ahoy.visit_duration = 30.minutes
Let’s associate orders with visits. Add a visit_id column on orders and do:
class Order < ActiveRecord::Base visitable end
When a visitor places an order, the visit_id column is automatically set.
:tada: Magic!
Customize the column and class name with:
visitable :sign_up_visit, class_name: "Visit"
To attach the user with Doorkeeper, be sure you have a current_resource_owner method in ApplicationController.
class ApplicationController < ActionController::Base private def current_resource_owner User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token end end
By default, geocoding is performed inline. For performance, move it to the background. Add Active Job and set:
Ahoy.geocode = :async
Or disable it with:
Ahoy.geocode = false
To change the queue name (ahoy by default):
Ahoy.job_queue = :low_priority
Visitor and visit ids are generated on the first request (so you can use them immediately), but the track_visit method isn’t called until the JavaScript library posts to the server. This prevents browsers with cookies disabled from creating multiple visits and ensures visits are not created for API endpoints. Change this with:
Ahoy.track_visits_immediately = true
Note: It’s highly recommended to perform geocoding in the background with this option.
You can exclude API endpoints and other actions with:
skip_before_filter :track_ahoy_visit
Ahoy is built with developers in mind. You can run the following code in your browser’s console.
Force a new visit
ahoy.reset(); // then reload the page
Log messages
ahoy.debug();
Turn off logging
ahoy.debug(false);
Debug endpoint requests in Ruby
Ahoy.quiet = false
How you explore the data depends on the data store used.
Here are ways to do it with ActiveRecord.
Visit.group(:search_keyword).count Visit.group(:country).count Visit.group(:referring_domain).count
Chartkick and Groupdate make it super easy to visualize the data.
<%= line_chart Visit.group_by_day(:started_at).count %>
See where orders are coming from with simple joins:
Order.joins(:visit).group("referring_domain").count Order.joins(:visit).group("city").count Order.joins(:visit).group("device_type").count
To see the visits for a given user, create an association:
class User < ActiveRecord::Base has_many :visits end
And use:
user = User.first user.visits
viewed_store_ids = Ahoy::Event.where(name: "Viewed store").uniq.pluck(:user_id) added_item_ids = Ahoy::Event.where(user_id: viewed_store_ids, name: "Added item to cart").uniq.pluck(:user_id) viewed_checkout_ids = Ahoy::Event.where(user_id: added_item_ids, name: "Viewed checkout").uniq.pluck(:user_id)
The same approach also works with visitor ids.
When a user launches the app, create a visit.
Generate a visit_id and visitor_id as UUIDs.
Send these values in the Ahoy-Visit and Ahoy-Visitor headers with all requests.
Send a POST request to /ahoy/visits with:
iOS, Android, etc.1.0.07.0.6After 4 hours of inactivity, create another visit and use the updated visit id.
Send a POST request as Content-Type: application/json to /ahoy/events with:
5aea7b70-182d-4070-b062-b0a09699ad5e - UUIDViewed item{"item_id": 123}2014-06-17T00:00:00-07:00 - ISO 8601Ahoy-Visit and Ahoy-Visitor headersUse an array to pass multiple events at once.
rails g migration change_properties_to_jsonb_on_ahoy_events
And add:
def up change_column :ahoy_events, :properties, :jsonb, using: "properties::jsonb" end def down change_column :ahoy_events, :properties, :json end
Note: This will lock the table while the migration is running.
Add the following code to the end of config/intializers/ahoy.rb.
class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore uses_deprecated_subscribers end
If you use Ahoy::Event to track events, copy it into your project.
module Ahoy class Event < ActiveRecord::Base self.table_name = "ahoy_events" belongs_to :visit belongs_to :user, polymorphic: true serialize :properties, JSON end end
That’s it! To fix deprecations, keep reading.
Remove ahoy_visit from your visit model and replace it with:
class Visit < ActiveRecord::Base belongs_to :user, polymorphic: true end
Remove uses_deprecated_subscribers from Ahoy::Store.
If you have a custom subscriber, copy the track method to track_event in Ahoy::Store.
class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore def track_event(name, properties, options) # code copied from the track method in your subscriber end end
Ahoy no longer tracks the $authenticate event automatically.
To restore this behavior, use:
class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore def authenticate(user) super ahoy.track "$authenticate" end end
Replace the Ahoy.user_method with user method, and replace Ahoy.track_bots and Ahoy.exclude_method with exclude? method.
Skip this step if you do not use these options.
class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore def user # logic from Ahoy.user_method goes here controller.true_user end def exclude? # logic from Ahoy.track_bots and Ahoy.exclude_method goes here bot? || request.ip == "192.168.1.1" end end
You made it! Now, take advantage of Ahoy’s awesome new features, like easy customization and exception reporting.
Starting with 0.3.0, visit and visitor tokens are now UUIDs.
In 0.1.6, a big improvement was made to browser and os. Update existing visits with:
Visit.find_each do |visit| visit.set_technology visit.save! if visit.changed? end
Check out Ahoy.js.
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help: