ahoy_matey 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +324 -189
  4. data/ahoy_matey.gemspec +1 -0
  5. data/app/controllers/ahoy/base_controller.rb +5 -0
  6. data/app/controllers/ahoy/events_controller.rb +9 -7
  7. data/app/controllers/ahoy/visits_controller.rb +2 -1
  8. data/lib/ahoy.rb +37 -28
  9. data/lib/ahoy/controller.rb +12 -20
  10. data/lib/ahoy/deckhands/location_deckhand.rb +39 -0
  11. data/lib/ahoy/deckhands/request_deckhand.rb +41 -0
  12. data/lib/ahoy/deckhands/technology_deckhand.rb +49 -0
  13. data/lib/ahoy/deckhands/traffic_source_deckhand.rb +24 -0
  14. data/lib/ahoy/deckhands/utm_parameter_deckhand.rb +24 -0
  15. data/lib/ahoy/engine.rb +3 -1
  16. data/lib/ahoy/model.rb +19 -82
  17. data/lib/ahoy/stores/active_record_store.rb +63 -0
  18. data/lib/ahoy/stores/active_record_token_store.rb +113 -0
  19. data/lib/ahoy/stores/base_store.rb +65 -0
  20. data/lib/ahoy/stores/log_store.rb +47 -0
  21. data/lib/ahoy/stores/mongoid_store.rb +59 -0
  22. data/lib/ahoy/tracker.rb +108 -67
  23. data/lib/ahoy/version.rb +1 -1
  24. data/lib/ahoy/visit_properties.rb +58 -0
  25. data/lib/ahoy/warden.rb +1 -10
  26. data/lib/generators/ahoy/stores/active_record_events_generator.rb +44 -0
  27. data/lib/generators/ahoy/stores/active_record_generator.rb +17 -0
  28. data/lib/generators/ahoy/{events/active_record_generator.rb → stores/active_record_visits_generator.rb} +14 -6
  29. data/lib/generators/ahoy/stores/custom_generator.rb +16 -0
  30. data/lib/generators/ahoy/stores/log_generator.rb +16 -0
  31. data/lib/generators/ahoy/stores/mongoid_events_generator.rb +20 -0
  32. data/lib/generators/ahoy/stores/mongoid_generator.rb +16 -0
  33. data/lib/generators/ahoy/stores/mongoid_visits_generator.rb +20 -0
  34. data/{app/models/ahoy/event.rb → lib/generators/ahoy/stores/templates/active_record_event_model.rb} +2 -2
  35. data/lib/generators/ahoy/stores/templates/active_record_events_migration.rb +20 -0
  36. data/lib/generators/ahoy/stores/templates/active_record_initializer.rb +3 -0
  37. data/lib/generators/ahoy/stores/templates/active_record_visit_model.rb +4 -0
  38. data/lib/generators/ahoy/{templates/install.rb → stores/templates/active_record_visits_migration.rb} +6 -8
  39. data/lib/generators/ahoy/stores/templates/custom_initializer.rb +12 -0
  40. data/lib/generators/ahoy/stores/templates/log_initializer.rb +3 -0
  41. data/lib/generators/ahoy/stores/templates/mongoid_event_model.rb +12 -0
  42. data/lib/generators/ahoy/stores/templates/mongoid_initializer.rb +3 -0
  43. data/lib/generators/ahoy/stores/templates/mongoid_visit_model.rb +41 -0
  44. data/vendor/assets/javascripts/ahoy.js +19 -8
  45. metadata +45 -8
  46. data/lib/generators/ahoy/events/templates/create_events.rb +0 -20
  47. data/lib/generators/ahoy/events/templates/initializer.rb +0 -1
  48. data/lib/generators/ahoy/install_generator.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2226bcc4712d1729f93cc68a4a01ac03eef2ee0a
4
- data.tar.gz: fc0f05b5df70d3fddbb8f888bc7a136146b8cf47
3
+ metadata.gz: eee3fa6c02d811dff0ae4091ab08589366949211
4
+ data.tar.gz: 953da9d5b867bfb6c8abff089faa3ee06b965b0d
5
5
  SHA512:
6
- metadata.gz: f1d5a9cff762a21c7690eabea4100b842fa419fb1b0094117e4d0f34500c131a9738a8c83f4d52ec397f8c951bbd7a99f55b6a837acc99f227d2457d528495a8
7
- data.tar.gz: 047ed1ac5af0529aa172640629ca4101dff2659cc21452b4adb4f4d5219b684eae535d40f2d55b56ff9d0a65d440853bcf7bdf750da054afe2c4c004170fe2dd
6
+ metadata.gz: 4f37f8317be93f3c5192bdbc4b79fabdfa995d97da6385ad1eeb90074ea3ef8d9d4896e7f51ad4961e63f863d6269eb0fe8b59168d632db4de83b9ab158eb0ea
7
+ data.tar.gz: 402780cfd8f187c0f084562ae853678f18e43ce80b331e5820843e59b823e8733d12de0fd2d2c2413cde8ea596b9c474e36a9ec70c81f26aeb1c62f143aa1d05
@@ -1,3 +1,11 @@
1
+ ## 1.0.0
2
+
3
+ - Added support for any data store, and Mongoid out of the box
4
+ - Added `track_visits_immediately` option
5
+ - Added exception catching and reporting
6
+ - Visits expire after inactivity, not fixed interval
7
+ - Added `visit_duration` and `visitor_duration` options
8
+
1
9
  ## 0.3.2
2
10
 
3
11
  - Fixed bot exclusion for visits
data/README.md CHANGED
@@ -2,26 +2,11 @@
2
2
 
3
3
  :fire: Simple, powerful analytics for Rails
4
4
 
5
- Visits are stored in **your database** so you can easily combine them with other data.
6
-
7
- You get:
8
-
9
- - **traffic source** - referrer, referring domain, landing page, search keyword
10
- - **location** - country, region, and city
11
- - **technology** - browser, OS, and device type
12
- - **utm parameters** - source, medium, term, content, campaign
13
-
14
- Track events in:
15
-
16
- - JavaScript
17
- - Ruby
18
- - Native apps
19
-
20
- And store them wherever you’d like - your database, logs, external services, or all of them.
5
+ Ahoy makes it easy to track visitors and users. Track visits (sessions) and events in Ruby, JavaScript, and native apps. Works with any data store so you can easily scale.
21
6
 
22
7
  :postbox: To track emails, check out [Ahoy Email](https://github.com/ankane/ahoy_email).
23
8
 
24
- No Ruby? Check out [Ahoy.js](https://github.com/ankane/ahoy.js).
9
+ See [upgrade instructions](#upgrading) on how to move to 1.0.
25
10
 
26
11
  ## Installation
27
12
 
@@ -31,202 +16,308 @@ Add this line to your application’s Gemfile:
31
16
  gem 'ahoy_matey'
32
17
  ```
33
18
 
34
- And run the generator. This creates a model to store visits.
19
+ And add the javascript file in `app/assets/javascripts/application.js` after jQuery.
20
+
21
+ ```javascript
22
+ //= require jquery
23
+ //= require ahoy
24
+ ```
25
+
26
+ ## Choose a Data Store
27
+
28
+ ### ActiveRecord
29
+
30
+ #### PostgreSQL
35
31
 
36
32
  ```sh
37
- rails generate ahoy:install
33
+ rails generate ahoy:stores:active_record -d postgresql
38
34
  rake db:migrate
39
35
  ```
40
36
 
41
- Lastly, include the javascript file in `app/assets/javascripts/application.js` after jQuery.
37
+ #### MySQL and SQLite
42
38
 
43
- ```javascript
44
- //= require jquery
45
- //= require ahoy
39
+ Add [activeuuid](https://github.com/jashmenn/activeuuid) to your Gemfile.
40
+
41
+ ```ruby
42
+ gem 'activeuuid', '>= 0.5.0'
46
43
  ```
47
44
 
48
- We recommend using traditional analytics services like [Google Analytics](http://www.google.com/analytics/) as well.
45
+ And run:
49
46
 
50
- ## How It Works
47
+ ```sh
48
+ rails generate ahoy:stores:active_record
49
+ rake db:migrate
50
+ ```
51
51
 
52
- When someone visits your website, Ahoy creates a visit with lots of useful information.
52
+ If you just want visits, run:
53
53
 
54
- Use the `current_visit` method to access it.
54
+ ```sh
55
+ rails generate ahoy:stores:active_record_visits
56
+ rake db:migrate
57
+ ```
55
58
 
56
- Explore your visits with queries like:
59
+ ### Mongoid
57
60
 
58
- ```ruby
59
- Visit.group(:search_keyword).count
60
- Visit.group(:country).count
61
- Visit.group(:referring_domain).count
61
+ ```sh
62
+ rails generate ahoy:stores:mongoid
62
63
  ```
63
64
 
64
- [Chartkick](http://chartkick.com/) and [Groupdate](https://github.com/ankane/groupdate) make it super easy to visualize the data.
65
+ ### Logs
65
66
 
66
- ```erb
67
- <%= line_chart Visit.group_by_day(:created_at).count %>
67
+ ```sh
68
+ rails generate ahoy:stores:log
68
69
  ```
69
70
 
70
- ### The Power
71
+ This logs visits to `log/visits.log` and events to `log/events.log`.
71
72
 
72
- This information is great on its own, but super powerful when combined with other models.
73
+ ### Custom
73
74
 
74
- Let’s associate orders with visits.
75
+ ```sh
76
+ rails generate ahoy:stores:custom
77
+ ```
78
+
79
+ This creates a class for you to fill out.
75
80
 
76
81
  ```ruby
77
- class Order < ActiveRecord::Base
78
- visitable
82
+ class Ahoy::Store < Ahoy::Stores::BaseStore
83
+
84
+ def track_visit(options)
85
+ end
86
+
87
+ def track_event(name, properties, options)
88
+ end
89
+
79
90
  end
80
91
  ```
81
92
 
82
- When a visitor places an order, the `visit_id` column is automatically set.
93
+ ## How It Works
83
94
 
84
- :tada: Magic!
95
+ ### Visits
85
96
 
86
- See where orders are coming from with simple joins:
97
+ When someone visits your website, Ahoy creates a visit with lots of useful information.
98
+
99
+ - **traffic source** - referrer, referring domain, landing page, search keyword
100
+ - **location** - country, region, and city
101
+ - **technology** - browser, OS, and device type
102
+ - **utm parameters** - source, medium, term, content, campaign
103
+
104
+ Use the `current_visit` method to access it, and the `ahoy.visit_id` and `ahoy.visitor_id` methods to get the ids.
105
+
106
+ ### Events
107
+
108
+ Each event has a `name` and `properties`.
109
+
110
+ There are three ways to track events.
111
+
112
+ #### JavaScript
113
+
114
+ ```javascript
115
+ ahoy.track("Viewed book", {title: "The World is Flat"});
116
+ ```
117
+
118
+ or track events automatically with:
119
+
120
+ ```javascript
121
+ ahoy.trackAll();
122
+ ```
123
+
124
+ See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
125
+
126
+ #### Ruby
87
127
 
88
128
  ```ruby
89
- Order.joins(:visit).group("referring_domain").count
90
- Order.joins(:visit).group("city").count
91
- Order.joins(:visit).group("device_type").count
129
+ ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"
92
130
  ```
93
131
 
132
+ #### Native Apps
133
+
134
+ See the [HTTP spec](#native-apps) until libraries are built.
135
+
94
136
  ### Users
95
137
 
96
- Ahoy automatically attaches the `current_user` to the `current_visit`.
138
+ Ahoy automatically attaches the `current_user` to the visit.
97
139
 
98
- With [Devise](https://github.com/plataformatec/devise), it will attach the user even if he / she signs in after the visit starts.
140
+ With [Devise](https://github.com/plataformatec/devise), it will attach the user even if he or she signs in after the visit starts.
99
141
 
100
142
  With other authentication frameworks, add this to the end of your sign in method:
101
143
 
102
144
  ```ruby
103
- if current_visit and !current_visit.user
104
- current_visit.user = current_user
105
- current_visit.save!
106
- end
145
+ ahoy.authenticate(user)
107
146
  ```
108
147
 
109
- To see the visits for a given user, create an association:
148
+ ## Customize the Store
149
+
150
+ Stores are built to be highly customizable.
110
151
 
111
152
  ```ruby
112
- class User < ActiveRecord::Base
113
- has_many :visits
153
+ class Ahoy::Store < Ahoy::Stores::ActiveRecord
154
+ # add methods here
114
155
  end
115
156
  ```
116
157
 
117
- And use:
158
+ ### Exclude Bots and More
159
+
160
+ Bots are excluded by default. To change this, use:
118
161
 
119
162
  ```ruby
120
- user = User.first
121
- user.visits
163
+ def exclude?
164
+ bot? || request.ip == "192.168.1.1"
165
+ end
122
166
  ```
123
167
 
124
- ### UTM Parameters
168
+ ### Track Additional Values
125
169
 
126
- Use UTM parameters to track campaigns. [This is great for emails and social media](http://www.thunderseo.com/blog/utm-parameters/). Just add them to your links and Ahoy will pick them up.
127
-
128
- ```
129
- http://datakick.org/?utm_medium=email&utm_campaign=newsletter&utm_source=newsletter-2014-03
170
+ ```ruby
171
+ def track_visit(options)
172
+ super do |visit|
173
+ visit.gclid = visit_properties.landing_params["gclid"]
174
+ end
175
+ end
130
176
  ```
131
177
 
132
178
  or
133
179
 
180
+ ```ruby
181
+ def track_event(name, properties, options)
182
+ super do |event|
183
+ event.ip = request.ip
184
+ end
185
+ end
134
186
  ```
135
- http://datakick.org/?utm_medium=twitter&utm_campaign=social&utm_source=tweet123
187
+
188
+ ### Customize User
189
+
190
+ ```ruby
191
+ def user
192
+ controller.true_user
193
+ end
136
194
  ```
137
195
 
138
- ### Native Apps
196
+ ### Report Exceptions
139
197
 
140
- When a user launches the app, create a visit. Send a `POST` request to `/ahoy/visits` with:
198
+ Exceptions are caught by default so analytics do not break your app.
141
199
 
142
- - platform - `iOS`, `Android`, etc.
143
- - app_version - `1.0.0`
144
- - os_version - `7.0.6`
145
- - visit_token - `505f6201-8e10-44cf-ba1c-37271c8d0125`
146
- - visitor_token - `db3b1a8f-302b-42df-9cd0-06875f549474`
200
+ To report them to a service, use:
147
201
 
148
- Tokens must be [UUIDs](http://en.wikipedia.org/wiki/Universally_unique_identifier).
202
+ ```ruby
203
+ def report_exception(e)
204
+ Rollbar.report_exception(e)
205
+ end
206
+ ```
149
207
 
150
- Send the visit and visitor tokens in the `Ahoy-Visit` and `Ahoy-Visitor` headers with all requests.
208
+ ### Use Different Models
151
209
 
152
- After 4 hours, create another visit and use the updated visit token.
210
+ For ActiveRecord and Mongoid stores
153
211
 
154
- ## Events
212
+ ```ruby
213
+ def visit_model
214
+ CustomVisit
215
+ end
155
216
 
156
- Each event has a `name` and `properties`.
217
+ def event_model
218
+ CustomEvent
219
+ end
220
+ ```
157
221
 
158
- There are three ways to track events.
222
+ ## More Features
159
223
 
160
- #### JavaScript
224
+ ### Automatic Tracking
225
+
226
+ Page views
161
227
 
162
228
  ```javascript
163
- ahoy.track("Viewed book", {title: "The World is Flat"});
229
+ ahoy.trackView();
164
230
  ```
165
231
 
166
- or track all views and clicks with:
232
+ Clicks
167
233
 
168
234
  ```javascript
169
- ahoy.trackAll();
235
+ ahoy.trackClicks();
170
236
  ```
171
237
 
172
- See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
238
+ Rails actions
173
239
 
174
- #### Ruby
240
+ ```ruby
241
+ class ApplicationController < ActionController::Base
242
+ after_filter :track_action
243
+
244
+ protected
245
+
246
+ def track_action
247
+ ahoy.track "Processed #{controller_name}##{action_name}", request.filtered_parameters
248
+ end
249
+ end
250
+ ```
251
+
252
+ ### Multiple Subdomains
253
+
254
+ To track visits across multiple subdomains, use:
175
255
 
176
256
  ```ruby
177
- ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"
257
+ Ahoy.cookie_domain = :all
178
258
  ```
179
259
 
180
- #### Native Apps
260
+ ### Visit Duration
181
261
 
182
- Send a `POST` request to `/ahoy/events` with:
262
+ By default, a new visit is created after 4 hours of inactivity.
183
263
 
184
- - name
185
- - properties
186
- - user token (depends on your authentication framework)
187
- - `Ahoy-Visit` header
264
+ Change this with:
265
+
266
+ ```ruby
267
+ Ahoy.visit_duration = 30.minutes
268
+ ```
188
269
 
189
- Requests should have `Content-Type: application/json`.
270
+ ### ActiveRecord
271
+
272
+ Let’s associate orders with visits.
190
273
 
191
- ### Storing Events
274
+ ```ruby
275
+ class Order < ActiveRecord::Base
276
+ visitable
277
+ end
278
+ ```
192
279
 
193
- You choose how to store events.
280
+ When a visitor places an order, the `visit_id` column is automatically set.
194
281
 
195
- #### ActiveRecord
282
+ :tada: Magic!
196
283
 
197
- Create an `Ahoy::Event` model to store events.
284
+ Customize the column and class name with:
198
285
 
199
- ```sh
200
- rails generate ahoy:events:active_record
201
- rake db:migrate
286
+ ```ruby
287
+ visitable :sign_up_visit, class_name: "Visit"
202
288
  ```
203
289
 
204
- #### Custom
290
+ ### Doorkeeper
205
291
 
206
- Create your own subscribers in `config/initializers/ahoy.rb`.
292
+ To attach the user with [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper), be sure you have a `current_resource_owner` method in `ApplicationController`.
207
293
 
208
294
  ```ruby
209
- class LogSubscriber
295
+ class ApplicationController < ActionController::Base
296
+
297
+ private
210
298
 
211
- def track(name, properties, options = {})
212
- data = {
213
- name: name,
214
- properties: properties,
215
- time: options[:time].to_i,
216
- visit_id: options[:visit].try(:id),
217
- user_id: options[:user].try(:id),
218
- ip: options[:controller].try(:request).try(:remote_ip)
219
- }
220
- Rails.logger.info data.to_json
299
+ def current_resource_owner
300
+ User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
221
301
  end
222
302
 
223
303
  end
304
+ ```
305
+
306
+ ### Track Visits Immediately
224
307
 
225
- # and add it
226
- Ahoy.subscribers << LogSubscriber.new
308
+ 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:
309
+
310
+ ```ruby
311
+ Ahoy.track_visits_immediately = true
227
312
  ```
228
313
 
229
- Add as many subscribers as you’d like.
314
+ **Note:** At the moment, geocoding is performed in the foreground, which can slow down the first page load.
315
+
316
+ You can exclude API endpoints and other actions with:
317
+
318
+ ```ruby
319
+ skip_before_filter :track_ahoy_visit
320
+ ```
230
321
 
231
322
  ## Development
232
323
 
@@ -256,142 +347,183 @@ Debug endpoint requests in Ruby
256
347
  Ahoy.quiet = false
257
348
  ```
258
349
 
259
- ### More
350
+ ## Explore the Data
260
351
 
261
- - Excludes bots
262
- - Degrades gracefully when cookies are disabled
263
- - Don’t need a field? Just remove it from the migration
264
- - Visits are 4 hours by default
352
+ How you explore the data depends on the data store used.
265
353
 
266
- ### Doorkeeper
267
-
268
- To attach the user with [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper), be sure you have a `current_resource_owner` method in `ApplicationController`.
354
+ Here are ways to do it with ActiveRecord.
269
355
 
270
356
  ```ruby
271
- class ApplicationController < ActionController::Base
272
-
273
- private
357
+ Visit.group(:search_keyword).count
358
+ Visit.group(:country).count
359
+ Visit.group(:referring_domain).count
360
+ ```
274
361
 
275
- def current_resource_owner
276
- User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
277
- end
362
+ [Chartkick](http://chartkick.com/) and [Groupdate](https://github.com/ankane/groupdate) make it super easy to visualize the data.
278
363
 
279
- end
364
+ ```erb
365
+ <%= line_chart Visit.group_by_day(:created_at).count %>
280
366
  ```
281
367
 
282
- ## Reference
368
+ See where orders are coming from with simple joins:
283
369
 
284
- To track visits across multiple subdomains, you must set the domain in two places (at the moment).
370
+ ```ruby
371
+ Order.joins(:visit).group("referring_domain").count
372
+ Order.joins(:visit).group("city").count
373
+ Order.joins(:visit).group("device_type").count
374
+ ```
285
375
 
286
- Add this to the `config/initializers/ahoy.rb` initializer:
376
+ To see the visits for a given user, create an association:
287
377
 
288
378
  ```ruby
289
- Ahoy.domain = "yourdomain.com"
379
+ class User < ActiveRecord::Base
380
+ has_many :visits
381
+ end
290
382
  ```
291
383
 
292
- and add this **before** the javascript files:
384
+ And use:
293
385
 
294
- ```javascript
295
- var ahoy = {"domain": "yourdomain.com"};
386
+ ```ruby
387
+ user = User.first
388
+ user.visits
296
389
  ```
297
390
 
298
- Change the platform on the web
391
+ ### Create Funnels
299
392
 
300
- ```javascript
301
- var ahoy = {"platform": "Mobile Web"}
393
+ ```ruby
394
+ viewed_store_ids = Ahoy::Event.where(name: "Viewed store").uniq.pluck(:user_id)
395
+ added_item_ids = Ahoy::Event.where(user_id: viewed_store_ids, name: "Added item to cart").uniq.pluck(:user_id)
396
+ viewed_checkout_ids = Ahoy::Event.where(user_id: added_item_ids, name: "Viewed checkout").uniq.pluck(:user_id)
302
397
  ```
303
398
 
304
- Track additional values
399
+ The same approach also works with visitor ids.
305
400
 
306
- ```ruby
307
- class Visit < ActiveRecord::Base
308
- ahoy_visit
401
+ ## Native Apps
309
402
 
310
- before_create :set_gclid
403
+ ### Visits
311
404
 
312
- def set_gclid
313
- self.gclid = landing_params["gclid"]
314
- end
405
+ When a user launches the app, create a visit.
315
406
 
316
- end
317
- ```
407
+ Generate a `visit_id` and `visitor_id` as [UUIDs](http://en.wikipedia.org/wiki/Universally_unique_identifier).
318
408
 
319
- Use a method besides `current_user`
409
+ Send these values in the `Ahoy-Visit` and `Ahoy-Visitor` headers with all requests.
320
410
 
321
- ```ruby
322
- Ahoy.user_method = :true_user
323
- ```
411
+ Send a `POST` request to `/ahoy/visits` with:
324
412
 
325
- or use a Proc
413
+ - platform - `iOS`, `Android`, etc.
414
+ - app_version - `1.0.0`
415
+ - os_version - `7.0.6`
326
416
 
327
- ```ruby
328
- Ahoy.user_method = proc {|controller| controller.current_user }
329
- ```
417
+ After 4 hours of inactivity, create another visit and use the updated visit id.
330
418
 
331
- Customize visitable
419
+ ### Events
332
420
 
333
- ```ruby
334
- visitable :sign_up_visit, class_name: "Visit"
335
- ```
421
+ Send a `POST` request as `Content-Type: application/json` to `/ahoy/events` with:
336
422
 
337
- Track view
423
+ - id - `5aea7b70-182d-4070-b062-b0a09699ad5e` - UUID
424
+ - name - `Viewed item`
425
+ - properties - `{"item_id": 123}`
426
+ - time - `2014-06-17T00:00:00-07:00` - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)
427
+ - `Ahoy-Visit` and `Ahoy-Visitor` headers
428
+ - user token (depends on your authentication framework)
338
429
 
339
- ```javascript
340
- ahoy.trackView();
341
- ```
430
+ Use an array to pass multiple events at once.
342
431
 
343
- Track clicks
432
+ ## Upgrading
344
433
 
345
- ```javascript
346
- ahoy.trackClicks();
434
+ ### 1.0.0
435
+
436
+ Add the following code to the end of `config/intializers/ahoy.rb`.
437
+
438
+ ```ruby
439
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
440
+ uses_deprecated_subscribers
441
+ end
347
442
  ```
348
443
 
349
- Track all Rails actions
444
+ If you use `Ahoy::Event` to track events, copy it into your project.
350
445
 
351
446
  ```ruby
352
- class ApplicationController < ActionController::Base
353
- after_filter :track_action
447
+ module Ahoy
448
+ class Event < ActiveRecord::Base
449
+ self.table_name = "ahoy_events"
354
450
 
355
- protected
451
+ belongs_to :visit
452
+ belongs_to :user, polymorphic: true
356
453
 
357
- def track_action
358
- ahoy.track "Hit action", request.filtered_parameters
454
+ serialize :properties, JSON
359
455
  end
360
456
  end
361
457
  ```
362
458
 
363
- Use a different model for visits
459
+ That’s it! To fix deprecations, keep reading.
364
460
 
365
- ```ruby
366
- Ahoy.visit_model = UserVisit
461
+ #### Visits
462
+
463
+ Remove `ahoy_visit` from your visit model and replace it with:
367
464
 
368
- # fix for Rails reloader in development
369
- ActionDispatch::Reloader.to_prepare do
370
- Ahoy.visit_model = UserVisit
465
+ ```ruby
466
+ class Visit < ActiveRecord::Base
467
+ belongs_to :user, polymorphic: true
371
468
  end
372
469
  ```
373
470
 
374
- Use a different model for events
471
+ #### Subscribers
472
+
473
+ Remove `uses_deprecated_subscribers` from `Ahoy::Store`.
474
+
475
+ If you have a custom subscriber, copy the `track` method to `track_event` in `Ahoy::Store`.
375
476
 
376
477
  ```ruby
377
- Ahoy.subscribers << Ahoy::Subscribers::ActiveRecord.new(model: Event)
478
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
479
+
480
+ def track_event(name, properties, options)
481
+ # code copied from the track method in your subscriber
482
+ end
483
+
484
+ end
378
485
  ```
379
486
 
380
- Exclude visits and events
487
+ #### Authentication
488
+
489
+ Ahoy no longer tracks the `$authenticate` event automatically.
490
+
491
+ To restore this behavior, use:
381
492
 
382
493
  ```ruby
383
- Ahoy.exclude_method = proc do |controller, request|
384
- request.ip == "192.168.1.1"
494
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
495
+
496
+ def authenticate(user)
497
+ super
498
+ ahoy.track "$authenticate"
499
+ end
500
+
385
501
  end
386
502
  ```
387
503
 
388
- Track bots
504
+ #### Global Options
505
+
506
+ Replace the `Ahoy.user_method` with `user` method, and replace `Ahoy.track_bots` and `Ahoy.exclude_method` with `exclude?` method.
507
+
508
+ Skip this step if you do not use these options.
389
509
 
390
510
  ```ruby
391
- Ahoy.track_bots = true
511
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
512
+
513
+ def user
514
+ # logic from Ahoy.user_method goes here
515
+ controller.true_user
516
+ end
517
+
518
+ def exclude?
519
+ # logic from Ahoy.track_bots and Ahoy.exclude_method goes here
520
+ bot? || request.ip == "192.168.1.1"
521
+ end
522
+
523
+ end
392
524
  ```
393
525
 
394
- ## Upgrading
526
+ You made it! Now, take advantage of Ahoy’s awesome new features, like easy customization and exception reporting.
395
527
 
396
528
  ### 0.3.0
397
529
 
@@ -410,10 +542,13 @@ end
410
542
 
411
543
  ## TODO
412
544
 
413
- - better readme
414
545
  - simple dashboard
415
546
  - turn off modules
416
547
 
548
+ ## No Ruby?
549
+
550
+ Check out [Ahoy.js](https://github.com/ankane/ahoy.js).
551
+
417
552
  ## History
418
553
 
419
554
  View the [changelog](https://github.com/ankane/ahoy/blob/master/CHANGELOG.md)