ahoy_matey 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cea71919e25f8f3b9ce9f3ccea43f8d11ec29d1995b3c5078428a8d4a7948457
4
- data.tar.gz: 81316ad1b9fc956bf0ece8c23c63570d5f333e0f7c781406e1b2214e965feebb
3
+ metadata.gz: 021c0b07d7cddf6a22125683bb5b1d18a078f1ff1f504cca066d4069c6014357
4
+ data.tar.gz: d49b52ce94f4c7436df4d054324639f9e5cd951fe459a11ca28aaab36231bd19
5
5
  SHA512:
6
- metadata.gz: c52e5f32c8fd7f9d070867e8d53868a58365430ed6d7bfa3baa1dd826f042875d42fadddc7991bf5c1c0b836021dd1b2634e8c2e43fa88a055dff9b8aeae70e5
7
- data.tar.gz: e3cdb04028a3277f678f65bf713d3a93339be369d4ed8af73a87bddd549b2ffd7983abd91443858e4411459442b8e292612381ea3ff731ce53d8f0b50f995857
6
+ metadata.gz: 6082fea0363bb2f25b7309876a36a1982894d3dcc2dc905da2278ab0ca41257f1c322001c86deb36168dbd1649c87199ec65990c9e7307b407b3f96fdb7a2bac
7
+ data.tar.gz: d833375e6cdb800b51072ed3d3c269e55c21c06287cde4a351022c331b36dd4b9aa812afa7b33156ee7a7b745d08a53b0d726000a919fd616300c0f6149a51b4
data/CHANGELOG.md CHANGED
@@ -1,8 +1,23 @@
1
+ ## 4.1.0 (2022-06-12)
2
+
3
+ - Ensure `exclude_method` is only called once per request
4
+ - Fixed error with Mongoid when `Mongoid.raise_not_found_error` is `true`
5
+ - Fixed association for Mongoid
6
+
7
+ ## 4.0.3 (2022-01-15)
8
+
9
+ - Support for `importmap-rails` is no longer experimental
10
+ - Fixed asset precompilation error with `importmap-rails`
11
+
12
+ ## 4.0.2 (2021-11-06)
13
+
14
+ - Added experimental support for `importmap-rails`
15
+
1
16
  ## 4.0.1 (2021-08-18)
2
17
 
3
18
  - Added support for `where_event`, `where_props`, and `where_group` for SQLite
4
- - Fixed results with `where_event`
5
- - Fixed results with `where_props` and `where_group` when used with other scopes
19
+ - Fixed results with `where_event` for MySQL, MariaDB, and Postgres `hstore`
20
+ - Fixed results with `where_props` and `where_group` when used with other scopes for MySQL, MariaDB, and Postgres `hstore`
6
21
 
7
22
  ## 4.0.0 (2021-08-14)
8
23
 
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2021 Andrew Kane
1
+ Copyright (c) 2014-2022 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -17,7 +17,7 @@ Track visits and events in Ruby, JavaScript, and native apps. Data is stored in
17
17
  Add this line to your application’s Gemfile:
18
18
 
19
19
  ```ruby
20
- gem 'ahoy_matey'
20
+ gem "ahoy_matey"
21
21
  ```
22
22
 
23
23
  And run:
@@ -48,6 +48,18 @@ And restart your web server.
48
48
 
49
49
  ### JavaScript
50
50
 
51
+ For Rails 7 / Importmap, add to `config/importmap.rb`:
52
+
53
+ ```ruby
54
+ pin "ahoy", to: "ahoy.js"
55
+ ```
56
+
57
+ And add to `app/javascript/application.js`:
58
+
59
+ ```javascript
60
+ import "ahoy"
61
+ ```
62
+
51
63
  For Rails 6 / Webpacker, run:
52
64
 
53
65
  ```sh
@@ -57,7 +69,7 @@ yarn add ahoy.js
57
69
  And add to `app/javascript/packs/application.js`:
58
70
 
59
71
  ```javascript
60
- import ahoy from "ahoy.js";
72
+ import ahoy from "ahoy.js"
61
73
  ```
62
74
 
63
75
  For Rails 5 / Sprockets, add to `app/assets/javascripts/application.js`:
@@ -185,9 +197,9 @@ Order.joins(:ahoy_visit).group("device_type").count
185
197
  Here’s what the migration to add the `ahoy_visit_id` column should look like:
186
198
 
187
199
  ```ruby
188
- class AddVisitIdToOrders < ActiveRecord::Migration[6.1]
200
+ class AddAhoyVisitToOrders < ActiveRecord::Migration[7.0]
189
201
  def change
190
- add_column :orders, :ahoy_visit_id, :bigint
202
+ add_reference :orders, :ahoy_visit
191
203
  end
192
204
  end
193
205
  ```
@@ -349,7 +361,7 @@ Ahoy uses [Geocoder](https://github.com/alexreisner/geocoder) for geocoding. We
349
361
  To enable geocoding, add this line to your application’s Gemfile:
350
362
 
351
363
  ```ruby
352
- gem 'geocoder'
364
+ gem "geocoder"
353
365
  ```
354
366
 
355
367
  And update `config/initializers/ahoy.rb`:
@@ -369,7 +381,7 @@ Ahoy.job_queue = :low_priority
369
381
  For privacy and performance, we recommend geocoding locally. Add this line to your application’s Gemfile:
370
382
 
371
383
  ```ruby
372
- gem 'maxminddb'
384
+ gem "maxminddb"
373
385
  ```
374
386
 
375
387
  For city-level geocoding, download the [GeoLite2 City database](https://dev.maxmind.com/geoip/geoip2/geolite2/) and create `config/initializers/geocoder.rb` with:
@@ -488,6 +500,8 @@ Previously set cookies are automatically deleted. If you use JavaScript tracking
488
500
  ahoy.configure({cookies: false});
489
501
  ```
490
502
 
503
+ Note: With anonymity sets, visits no longer expire after 4 hours of inactivity. A new visit is only created when the IP mask or user agent changes (for instance, when a user updates their browser). There are plans to address this in the next major version.
504
+
491
505
  ## Data Retention
492
506
 
493
507
  Data should only be retained for as long as it’s needed. Delete older data with:
@@ -661,7 +675,7 @@ Group by properties with:
661
675
  Ahoy::Event.group_prop(:product_id, :category).count
662
676
  ```
663
677
 
664
- Note: MySQL and MariaDB always return string keys (include `"null"` for `nil`) for `group_prop`.
678
+ Note: MySQL and MariaDB always return string keys (including `"null"` for `nil`) for `group_prop`.
665
679
 
666
680
  ### Funnels
667
681
 
@@ -694,6 +708,24 @@ daily_visits = Ahoy::Visit.group_by_day(:started_at).count # uses Groupdate
694
708
  Prophet.forecast(daily_visits)
695
709
  ```
696
710
 
711
+ ### Anomaly Detection
712
+
713
+ To detect anomalies in visits and events, check out [AnomalyDetection.rb](https://github.com/ankane/AnomalyDetection.rb).
714
+
715
+ ```ruby
716
+ daily_visits = Ahoy::Visit.group_by_day(:started_at).count # uses Groupdate
717
+ AnomalyDetection.detect(daily_visits, period: 7)
718
+ ```
719
+
720
+ ### Breakout Detection
721
+
722
+ To detect breakouts in visits and events, check out [Breakout](https://github.com/ankane/breakout).
723
+
724
+ ```ruby
725
+ daily_visits = Ahoy::Visit.group_by_day(:started_at).count # uses Groupdate
726
+ Breakout.detect(daily_visits)
727
+ ```
728
+
697
729
  ### Recommendations
698
730
 
699
731
  To make recommendations based on events, check out [Disco](https://github.com/ankane/disco#ahoy).
@@ -754,7 +786,7 @@ There are two notable changes to geocoding:
754
786
  2. The `geocoder` gem is now an optional dependency. To use geocoding, add it to your Gemfile:
755
787
 
756
788
  ```ruby
757
- gem 'geocoder'
789
+ gem "geocoder"
758
790
  ```
759
791
 
760
792
  Also, check out the [upgrade notes](https://github.com/ankane/ahoy.js#upgrading) for Ahoy.js.
@@ -781,10 +813,26 @@ bundle install
781
813
  bundle exec rake test
782
814
  ```
783
815
 
784
- To test query methods, start PostgreSQL, MySQL, and MongoDB and use:
816
+ To test Mongoid, use:
785
817
 
786
818
  ```sh
819
+ ADAPTER=mongoid bundle exec rake test
820
+ ```
821
+
822
+ To test query methods, use:
823
+
824
+ ```sh
825
+ # Postgres
787
826
  createdb ahoy_test
827
+ bundle exec rake test:query_methods:postgresql
828
+
829
+ # SQLite
830
+ bundle exec rake test:query_methods:sqlite
831
+
832
+ # MySQL and MariaDB
788
833
  mysqladmin create ahoy_test
789
- bundle exec rake test:query_methods
834
+ bundle exec rake test:query_methods:mysql
835
+
836
+ # MongoDB
837
+ bundle exec rake test:query_methods:mongoid
790
838
  ```
@@ -1,4 +1,5 @@
1
1
  # for smooth update from Ahoy 1 -> 2
2
+ # TODO remove in 5.0
2
3
  module Ahoy
3
4
  class GeocodeJob < ActiveJob::Base
4
5
  queue_as { Ahoy.job_queue }
@@ -53,7 +53,12 @@ module Ahoy
53
53
 
54
54
  def visit
55
55
  unless defined?(@visit)
56
- @visit = visit_model.find_by(visit_token: ahoy.visit_token) if ahoy.visit_token
56
+ if defined?(Mongoid::Document) && visit_model < Mongoid::Document
57
+ # find_by raises error by default when not found
58
+ @visit = visit_model.where(visit_token: ahoy.visit_token).first if ahoy.visit_token
59
+ else
60
+ @visit = visit_model.find_by(visit_token: ahoy.visit_token) if ahoy.visit_token
61
+ end
57
62
  end
58
63
  @visit
59
64
  end
data/lib/ahoy/engine.rb CHANGED
@@ -26,5 +26,12 @@ module Ahoy
26
26
  alias_method :call, :call_with_quiet_ahoy
27
27
  end
28
28
  end
29
+
30
+ # for importmap
31
+ initializer "ahoy.importmap" do |app|
32
+ if defined?(Importmap)
33
+ app.config.assets.precompile << "ahoy.js"
34
+ end
35
+ end
29
36
  end
30
37
  end
@@ -10,47 +10,38 @@ module Ahoy
10
10
  def where_props(properties)
11
11
  return all if properties.empty?
12
12
 
13
- relation = all
14
- if respond_to?(:columns_hash)
15
- column_type = columns_hash["properties"].type
16
- adapter_name = connection.adapter_name.downcase
17
- else
18
- adapter_name = "mongoid"
19
- end
13
+ adapter_name = respond_to?(:connection) ? connection.adapter_name.downcase : "mongoid"
20
14
  case adapter_name
21
15
  when "mongoid"
22
- relation = where(properties.to_h { |k, v| ["properties.#{k}", v] })
16
+ where(properties.to_h { |k, v| ["properties.#{k}", v] })
23
17
  when /mysql/
24
- relation = relation.where("JSON_CONTAINS(properties, ?, '$') = 1", properties.to_json)
18
+ where("JSON_CONTAINS(properties, ?, '$') = 1", properties.to_json)
25
19
  when /postgres|postgis/
26
- case column_type
27
- when :jsonb
28
- relation = relation.where("properties @> ?", properties.to_json)
20
+ case columns_hash["properties"].type
29
21
  when :hstore
30
- properties.each do |k, v|
31
- relation =
32
- if v.nil?
33
- relation.where("properties -> ? IS NULL", k.to_s)
34
- else
35
- relation.where("properties -> ? = ?", k.to_s, v.to_s)
36
- end
22
+ properties.inject(all) do |relation, (k, v)|
23
+ if v.nil?
24
+ relation.where("properties -> ? IS NULL", k.to_s)
25
+ else
26
+ relation.where("properties -> ? = ?", k.to_s, v.to_s)
27
+ end
37
28
  end
29
+ when :jsonb
30
+ where("properties @> ?", properties.to_json)
38
31
  else
39
- relation = relation.where("properties::jsonb @> ?", properties.to_json)
32
+ where("properties::jsonb @> ?", properties.to_json)
40
33
  end
41
34
  when /sqlite/
42
- properties.each do |k, v|
43
- relation =
44
- if v.nil?
45
- relation.where("JSON_EXTRACT(properties, ?) IS NULL", "$.#{k}")
46
- else
47
- relation.where("JSON_EXTRACT(properties, ?) = ?", "$.#{k}", v.as_json)
48
- end
35
+ properties.inject(all) do |relation, (k, v)|
36
+ if v.nil?
37
+ relation.where("JSON_EXTRACT(properties, ?) IS NULL", "$.#{k}")
38
+ else
39
+ relation.where("JSON_EXTRACT(properties, ?) = ?", "$.#{k}", v.as_json)
40
+ end
49
41
  end
50
42
  else
51
43
  raise "Adapter not supported: #{adapter_name}"
52
44
  end
53
- relation
54
45
  end
55
46
  alias_method :where_properties, :where_props
56
47
 
@@ -59,12 +50,7 @@ module Ahoy
59
50
  props.flatten!
60
51
 
61
52
  relation = all
62
- if respond_to?(:columns_hash)
63
- column_type = columns_hash["properties"].type
64
- adapter_name = connection.adapter_name.downcase
65
- else
66
- adapter_name = "mongoid"
67
- end
53
+ adapter_name = respond_to?(:connection) ? connection.adapter_name.downcase : "mongoid"
68
54
  case adapter_name
69
55
  when "mongoid"
70
56
  raise "Adapter not supported: #{adapter_name}"
@@ -77,6 +63,7 @@ module Ahoy
77
63
  # convert to jsonb to fix
78
64
  # could not identify an equality operator for type json
79
65
  # and for text columns
66
+ column_type = columns_hash["properties"].type
80
67
  cast = [:jsonb, :hstore].include?(column_type) ? "" : "::jsonb"
81
68
 
82
69
  props.each do |prop|
data/lib/ahoy/tracker.rb CHANGED
@@ -185,7 +185,10 @@ module Ahoy
185
185
  end
186
186
 
187
187
  def exclude?
188
- @store.exclude?
188
+ unless defined?(@exclude)
189
+ @exclude = @store.exclude?
190
+ end
191
+ @exclude
189
192
  end
190
193
 
191
194
  def report_exception(e)
data/lib/ahoy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "4.0.1"
2
+ VERSION = "4.1.0"
3
3
  end
data/lib/ahoy.rb CHANGED
@@ -126,7 +126,6 @@ ActiveSupport.on_load(:action_view) do
126
126
  include Ahoy::Helper
127
127
  end
128
128
 
129
- # Mongoid
130
129
  ActiveSupport.on_load(:mongoid) do
131
130
  Mongoid::Document::ClassMethods.include(Ahoy::Model)
132
131
  end
@@ -1,3 +1,4 @@
1
+ require "rails/generators"
1
2
  require "rails/generators/active_record"
2
3
 
3
4
  module Ahoy
@@ -2,7 +2,7 @@ class Ahoy::Event
2
2
  include Mongoid::Document
3
3
 
4
4
  # associations
5
- belongs_to :visit, index: true
5
+ belongs_to :visit, class_name: "Ahoy::Visit", index: true
6
6
  belongs_to :user, index: true, optional: true
7
7
 
8
8
  # fields
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_matey
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-18 00:00:00.000000000 Z
11
+ date: 2022-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
115
  requirements: []
116
- rubygems_version: 3.2.22
116
+ rubygems_version: 3.3.7
117
117
  signing_key:
118
118
  specification_version: 4
119
119
  summary: Simple, powerful, first-party analytics for Rails