ahoy_matey 3.0.4 → 3.0.5

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: 141aeb0d7f78023ecefb04f274637e06c68d6d8af9ece0ac583d8cff701b59f9
4
- data.tar.gz: f44945bbdad4be224a57b4e915175ef983c4c24ed28eca4accc8e5fcce171105
3
+ metadata.gz: 17572400fdaab440040c753cf23084f2a47868e5c1ed12229e85fd1904e9c937
4
+ data.tar.gz: cc917af046906e308830fa1ffa9543db1bc1fe0f79488ccaddef090e6366433d
5
5
  SHA512:
6
- metadata.gz: ee9f88551691cc6be92b5adf9bfd0495065e43510679a61377bc12082c44ac7b0cff544ca88b3157ec92d05432ff58e654b491c7e256eb2c6032b5517573e6e3
7
- data.tar.gz: 45565919c04c0f7c05cf87d0ef0f35fedd867cbd7569ee72a613770efab6a0c7dac1d884d6d0830c4f28efcf475ece191e7d44cb3712b18454c30b0de1658a4d
6
+ metadata.gz: 325caa06934a20bf7a58f573fff7359b7058cf63e3e7576c48faf1bd5d08ac2564810a28e5a775c3ac324170754db4de35d46f43c0b421f8c4977760af19d153
7
+ data.tar.gz: e7af674522e09e3fb472b52546f30d10b743e2b2814efd97162d05cb1d4f9b13615dce211cd83e291da16e370a86cf7d8d384b16ad60d8af07c8ced8fbd17f59
@@ -1,3 +1,8 @@
1
+ ## 3.0.5 (2020-09-09)
2
+
3
+ - Added `group_prop` method
4
+ - Use `datetime` type in migration
5
+
1
6
  ## 3.0.4 (2020-06-07)
2
7
 
3
8
  - Updated Ahoy.js to 0.3.6
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2019 Andrew Kane
1
+ Copyright (c) 2014-2020 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -435,7 +435,7 @@ Previously set cookies are automatically deleted.
435
435
 
436
436
  ## Data Retention
437
437
 
438
- Delete older data with:
438
+ Data should only be retained for as long as it’s needed. Delete older data with:
439
439
 
440
440
  ```ruby
441
441
  Ahoy::Visit.where("started_at < ?", 2.years.ago).find_in_batches do |visits|
@@ -445,6 +445,12 @@ Ahoy::Visit.where("started_at < ?", 2.years.ago).find_in_batches do |visits|
445
445
  end
446
446
  ```
447
447
 
448
+ You can use [Rollup](https://github.com/ankane/rollup) to aggregate important data before you do.
449
+
450
+ ```ruby
451
+ Ahoy::Visit.rollup("Visits", interval: "hour")
452
+ ```
453
+
448
454
  Delete data for a specific user with:
449
455
 
450
456
  ```ruby
@@ -580,7 +586,7 @@ Ahoy::Visit.group(:referring_domain).count
580
586
 
581
587
  ### Querying Events
582
588
 
583
- Ahoy provides two methods on the event model to make querying easier.
589
+ Ahoy provides a few methods on the event model to make querying easier.
584
590
 
585
591
  To query on both name and properties, you can use:
586
592
 
@@ -591,9 +597,17 @@ Ahoy::Event.where_event("Viewed product", product_id: 123).count
591
597
  Or just query properties with:
592
598
 
593
599
  ```ruby
594
- Ahoy::Event.where_props(product_id: 123).count
600
+ Ahoy::Event.where_props(product_id: 123, category: "Books").count
601
+ ```
602
+
603
+ Group by properties with:
604
+
605
+ ```ruby
606
+ Ahoy::Event.group_prop(:product_id, :category).count
595
607
  ```
596
608
 
609
+ Note: MySQL and MariaDB always return string keys (include `"null"` for `nil`) for `group_prop`.
610
+
597
611
  ### Funnels
598
612
 
599
613
  It’s easy to create funnels.
@@ -606,6 +620,29 @@ viewed_checkout_ids = Ahoy::Event.where(user_id: added_item_ids, name: "Viewed c
606
620
 
607
621
  The same approach also works with visitor tokens.
608
622
 
623
+ ### Rollups
624
+
625
+ Improve query performance by pre-aggregating data with [Rollup](https://github.com/ankane/rollup).
626
+
627
+ ```ruby
628
+ Ahoy::Event.where(name: "Viewed store").rollup("Store views")
629
+ ```
630
+
631
+ This is only needed if you have a lot of data.
632
+
633
+ ### Forecasting
634
+
635
+ To forecast future visits and events, check out [Prophet](https://github.com/ankane/prophet).
636
+
637
+ ```ruby
638
+ daily_visits = Ahoy::Visit.group_by_day(:started_at).count # uses Groupdate
639
+ Prophet.forecast(daily_visits)
640
+ ```
641
+
642
+ ### Recommendations
643
+
644
+ To make recommendations based on events, check out [Disco](https://github.com/ankane/disco#ahoy).
645
+
609
646
  ## Tutorials
610
647
 
611
648
  - [Tracking Metrics with Ahoy and Blazer](https://gorails.com/episodes/internal-metrics-with-ahoy-and-blazer)
@@ -722,3 +759,20 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
722
759
  - Fix bugs and [submit pull requests](https://github.com/ankane/ahoy/pulls)
723
760
  - Write, clarify, or fix documentation
724
761
  - Suggest or add new features
762
+
763
+ To get started with development:
764
+
765
+ ```sh
766
+ git clone https://github.com/ankane/ahoy.git
767
+ cd ahoy
768
+ bundle install
769
+ bundle exec rake test
770
+ ```
771
+
772
+ To test query methods, start PostgreSQL, MySQL, and MongoDB and use:
773
+
774
+ ```sh
775
+ createdb ahoy_test
776
+ mysqladmin create ahoy_test
777
+ bundle exec rake test:query_methods
778
+ ```
@@ -119,6 +119,10 @@ ActiveSupport.on_load(:action_view) do
119
119
  end
120
120
 
121
121
  # Mongoid
122
+ # TODO use
123
+ # ActiveSupport.on_load(:mongoid) do
124
+ # Mongoid::Document::ClassMethods.include(Ahoy::Model)
125
+ # end
122
126
  if defined?(ActiveModel)
123
127
  ActiveModel::Callbacks.include(Ahoy::Model)
124
128
  end
@@ -31,6 +31,7 @@ module Ahoy
31
31
  end
32
32
  else
33
33
  properties.each do |k, v|
34
+ # TODO cast to json instead
34
35
  relation = relation.where("properties REGEXP ?", "[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "").gsub("+", "\\\\+")}[,}]")
35
36
  end
36
37
  end
@@ -57,6 +58,7 @@ module Ahoy
57
58
  end
58
59
  else
59
60
  properties.each do |k, v|
61
+ # TODO cast to jsonb instead
60
62
  relation = relation.where("properties SIMILAR TO ?", "%[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "").gsub("+", "\\\\+")}[,}]%")
61
63
  end
62
64
  end
@@ -66,6 +68,49 @@ module Ahoy
66
68
  relation
67
69
  end
68
70
  alias_method :where_properties, :where_props
71
+
72
+ def group_prop(*props)
73
+ # like with group
74
+ props.flatten!
75
+
76
+ relation = self
77
+ if respond_to?(:columns_hash)
78
+ column_type = columns_hash["properties"].type
79
+ adapter_name = connection.adapter_name.downcase
80
+ else
81
+ adapter_name = "mongoid"
82
+ end
83
+ case adapter_name
84
+ when "mongoid"
85
+ raise "Adapter not supported: #{adapter_name}"
86
+ when /mysql/
87
+ if connection.try(:mariadb?)
88
+ props.each do |prop|
89
+ quoted_prop = connection.quote("$.#{prop}")
90
+ relation = relation.group("JSON_UNQUOTE(JSON_EXTRACT(properties, #{quoted_prop}))")
91
+ end
92
+ else
93
+ column = column_type == :json ? "properties" : "CAST(properties AS JSON)"
94
+ props.each do |prop|
95
+ quoted_prop = connection.quote("$.#{prop}")
96
+ relation = relation.group("JSON_UNQUOTE(JSON_EXTRACT(#{column}, #{quoted_prop}))")
97
+ end
98
+ end
99
+ when /postgres|postgis/
100
+ # convert to jsonb to fix
101
+ # could not identify an equality operator for type json
102
+ # and for text columns
103
+ cast = [:jsonb, :hstore].include?(column_type) ? "" : "::jsonb"
104
+
105
+ props.each do |prop|
106
+ quoted_prop = connection.quote(prop)
107
+ relation = relation.group("properties#{cast} -> #{quoted_prop}")
108
+ end
109
+ else
110
+ raise "Adapter not supported: #{adapter_name}"
111
+ end
112
+ relation
113
+ end
69
114
  end
70
115
  end
71
116
  end
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "3.0.4"
2
+ VERSION = "3.0.5"
3
3
  end
@@ -41,10 +41,10 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
41
41
  t.string :os_version
42
42
  t.string :platform
43
43
 
44
- t.timestamp :started_at
44
+ t.datetime :started_at
45
45
  end
46
46
 
47
- add_index :ahoy_visits, [:visit_token], unique: true
47
+ add_index :ahoy_visits, :visit_token, unique: true
48
48
 
49
49
  create_table :ahoy_events do |t|
50
50
  t.references :visit
@@ -52,7 +52,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
52
52
 
53
53
  t.string :name
54
54
  t.<%= properties_type %> :properties
55
- t.timestamp :time
55
+ t.datetime :time
56
56
  end
57
57
 
58
58
  add_index :ahoy_events, [:name, :time]<% if properties_type == "jsonb" %><% if rails52? %>
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: 3.0.4
4
+ version: 3.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-07 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -192,6 +192,34 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: browser
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '2.0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '2.0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: user_agent_parser
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
195
223
  description:
196
224
  email: andrew@chartkick.com
197
225
  executables: []