ahoy_matey 2.0.0 → 3.2.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 +5 -5
- data/CHANGELOG.md +112 -37
- data/CONTRIBUTING.md +9 -7
- data/LICENSE.txt +1 -1
- data/README.md +377 -63
- data/app/controllers/ahoy/base_controller.rb +14 -10
- data/app/controllers/ahoy/events_controller.rb +1 -1
- data/app/controllers/ahoy/visits_controller.rb +1 -0
- data/app/jobs/ahoy/geocode_v2_job.rb +3 -4
- data/lib/ahoy.rb +57 -2
- data/lib/ahoy/base_store.rb +32 -3
- data/lib/ahoy/controller.rb +21 -8
- data/lib/ahoy/database_store.rb +33 -16
- data/lib/ahoy/engine.rb +3 -1
- data/lib/ahoy/helper.rb +40 -0
- data/lib/ahoy/model.rb +2 -2
- data/lib/ahoy/query_methods.rb +46 -1
- data/lib/ahoy/tracker.rb +59 -27
- data/lib/ahoy/utils.rb +7 -0
- data/lib/ahoy/version.rb +1 -1
- data/lib/ahoy/visit_properties.rb +73 -37
- data/lib/generators/ahoy/activerecord_generator.rb +17 -26
- data/lib/generators/ahoy/base_generator.rb +1 -1
- data/lib/generators/ahoy/install_generator.rb +1 -1
- data/lib/generators/ahoy/mongoid_generator.rb +1 -5
- data/lib/generators/ahoy/templates/active_record_event_model.rb.tt +10 -0
- data/lib/generators/ahoy/templates/{active_record_migration.rb → active_record_migration.rb.tt} +14 -7
- data/lib/generators/ahoy/templates/active_record_visit_model.rb.tt +6 -0
- data/lib/generators/ahoy/templates/{base_store_initializer.rb → base_store_initializer.rb.tt} +8 -0
- data/lib/generators/ahoy/templates/database_store_initializer.rb.tt +10 -0
- data/lib/generators/ahoy/templates/{mongoid_event_model.rb → mongoid_event_model.rb.tt} +1 -1
- data/lib/generators/ahoy/templates/{mongoid_visit_model.rb → mongoid_visit_model.rb.tt} +9 -7
- data/vendor/assets/javascripts/ahoy.js +539 -552
- metadata +27 -204
- data/.github/ISSUE_TEMPLATE.md +0 -7
- data/.gitignore +0 -17
- data/Gemfile +0 -6
- data/Rakefile +0 -9
- data/ahoy_matey.gemspec +0 -36
- data/docs/Ahoy-2-Upgrade.md +0 -147
- data/docs/Data-Store-Examples.md +0 -240
- data/lib/generators/ahoy/templates/active_record_event_model.rb +0 -10
- data/lib/generators/ahoy/templates/active_record_visit_model.rb +0 -6
- data/lib/generators/ahoy/templates/database_store_initializer.rb +0 -5
- data/test/query_methods/mongoid_test.rb +0 -23
- data/test/query_methods/mysql_json_test.rb +0 -18
- data/test/query_methods/mysql_text_test.rb +0 -19
- data/test/query_methods/postgresql_hstore_test.rb +0 -20
- data/test/query_methods/postgresql_json_test.rb +0 -18
- data/test/query_methods/postgresql_jsonb_test.rb +0 -19
- data/test/query_methods/postgresql_text_test.rb +0 -19
- data/test/test_helper.rb +0 -100
data/docs/Data-Store-Examples.md
DELETED
@@ -1,240 +0,0 @@
|
|
1
|
-
# Data Store Examples
|
2
|
-
|
3
|
-
- [Kafka](#kafka)
|
4
|
-
- [RabbitMQ](#rabbitmq)
|
5
|
-
- [Fluentd](#fluentd)
|
6
|
-
- [NATS](#nats)
|
7
|
-
- [NSQ](#nsq)
|
8
|
-
- [Amazon Kinesis Firehose](#amazon-kinesis-firehose)
|
9
|
-
|
10
|
-
### Kafka
|
11
|
-
|
12
|
-
Add [ruby-kafka](https://github.com/zendesk/ruby-kafka) to your Gemfile.
|
13
|
-
|
14
|
-
```ruby
|
15
|
-
class Ahoy::Store < Ahoy::BaseStore
|
16
|
-
def track_visit(data)
|
17
|
-
post("ahoy_visits", data)
|
18
|
-
end
|
19
|
-
|
20
|
-
def track_event(data)
|
21
|
-
post("ahoy_events", data)
|
22
|
-
end
|
23
|
-
|
24
|
-
def geocode(data)
|
25
|
-
post("ahoy_geocode", data)
|
26
|
-
end
|
27
|
-
|
28
|
-
def authenticate(data)
|
29
|
-
post("ahoy_auth", data)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def post(topic, data)
|
35
|
-
producer.produce(data.to_json, topic: topic)
|
36
|
-
end
|
37
|
-
|
38
|
-
def producer
|
39
|
-
@producer ||= begin
|
40
|
-
client =
|
41
|
-
Kafka.new(
|
42
|
-
seed_brokers: ENV["KAFKA_URL"] || "localhost:9092",
|
43
|
-
logger: Rails.logger
|
44
|
-
)
|
45
|
-
producer = client.async_producer(delivery_interval: 3)
|
46
|
-
at_exit { producer.shutdown }
|
47
|
-
producer
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
```
|
52
|
-
|
53
|
-
### RabbitMQ
|
54
|
-
|
55
|
-
Add [bunny](https://github.com/ruby-amqp/bunny) to your Gemfile.
|
56
|
-
|
57
|
-
```ruby
|
58
|
-
class Ahoy::Store < Ahoy::BaseStore
|
59
|
-
def track_visit(data)
|
60
|
-
post("ahoy_visits", data)
|
61
|
-
end
|
62
|
-
|
63
|
-
def track_event(data)
|
64
|
-
post("ahoy_events", data)
|
65
|
-
end
|
66
|
-
|
67
|
-
def geocode(data)
|
68
|
-
post("ahoy_geocode", data)
|
69
|
-
end
|
70
|
-
|
71
|
-
def authenticate(data)
|
72
|
-
post("ahoy_auth", data)
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def post(topic, message)
|
78
|
-
channel.queue(topic, durable: true).publish(message.to_json)
|
79
|
-
end
|
80
|
-
|
81
|
-
def channel
|
82
|
-
@channel ||= begin
|
83
|
-
conn = Bunny.new
|
84
|
-
conn.start
|
85
|
-
conn.create_channel
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
```
|
90
|
-
|
91
|
-
### Fluentd
|
92
|
-
|
93
|
-
Add [fluent-logger](https://github.com/fluent/fluent-logger-ruby) to your Gemfile.
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
class Ahoy::Store < Ahoy::BaseStore
|
97
|
-
def track_visit(data)
|
98
|
-
post("ahoy_visits", data)
|
99
|
-
end
|
100
|
-
|
101
|
-
def track_event(data)
|
102
|
-
post("ahoy_events", data)
|
103
|
-
end
|
104
|
-
|
105
|
-
def geocode(data)
|
106
|
-
post("ahoy_geocode", data)
|
107
|
-
end
|
108
|
-
|
109
|
-
def authenticate(data)
|
110
|
-
post("ahoy_auth", data)
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
def post(topic, message)
|
116
|
-
logger.post(topic, message)
|
117
|
-
end
|
118
|
-
|
119
|
-
def logger
|
120
|
-
@logger ||= Fluent::Logger::FluentLogger.new("ahoy", host: "localhost", port: 24224)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
```
|
124
|
-
|
125
|
-
### NATS
|
126
|
-
|
127
|
-
Add [nats-pure](https://github.com/nats-io/pure-ruby-nats) to your Gemfile.
|
128
|
-
|
129
|
-
```ruby
|
130
|
-
class Ahoy::Store < Ahoy::BaseStore
|
131
|
-
def track_visit(data)
|
132
|
-
post("ahoy_visits", data)
|
133
|
-
end
|
134
|
-
|
135
|
-
def track_event(data)
|
136
|
-
post("ahoy_events", data)
|
137
|
-
end
|
138
|
-
|
139
|
-
def geocode(data)
|
140
|
-
post("ahoy_geocode", data)
|
141
|
-
end
|
142
|
-
|
143
|
-
def authenticate(data)
|
144
|
-
post("ahoy_auth", data)
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
def post(topic, data)
|
150
|
-
client.publish(topic, data.to_json)
|
151
|
-
end
|
152
|
-
|
153
|
-
def client
|
154
|
-
@client ||= begin
|
155
|
-
require "nats/io/client"
|
156
|
-
client = NATS::IO::Client.new
|
157
|
-
client.connect(servers: (ENV["NATS_URL"] || "nats://127.0.0.1:4222").split(","))
|
158
|
-
client
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
```
|
163
|
-
|
164
|
-
### NSQ
|
165
|
-
|
166
|
-
Add [nsq-ruby](https://github.com/wistia/nsq-ruby) to your Gemfile.
|
167
|
-
|
168
|
-
```ruby
|
169
|
-
class Ahoy::Store < Ahoy::BaseStore
|
170
|
-
def track_visit(data)
|
171
|
-
post("ahoy_visits", data)
|
172
|
-
end
|
173
|
-
|
174
|
-
def track_event(data)
|
175
|
-
post("ahoy_events", data)
|
176
|
-
end
|
177
|
-
|
178
|
-
def geocode(data)
|
179
|
-
post("ahoy_geocode", data)
|
180
|
-
end
|
181
|
-
|
182
|
-
def authenticate(data)
|
183
|
-
post("ahoy_auth", data)
|
184
|
-
end
|
185
|
-
|
186
|
-
private
|
187
|
-
|
188
|
-
def post(topic, data)
|
189
|
-
client.write_to_topic(topic, data.to_json)
|
190
|
-
end
|
191
|
-
|
192
|
-
def client
|
193
|
-
@client ||= begin
|
194
|
-
require "nsq"
|
195
|
-
client = Nsq::Producer.new(
|
196
|
-
nsqd: ENV["NSQ_URL"] || "127.0.0.1:4150"
|
197
|
-
)
|
198
|
-
at_exit { client.terminate }
|
199
|
-
client
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
```
|
204
|
-
|
205
|
-
### Amazon Kinesis Firehose
|
206
|
-
|
207
|
-
Add [aws-sdk-firehose](https://github.com/aws/aws-sdk-ruby) to your Gemfile.
|
208
|
-
|
209
|
-
```ruby
|
210
|
-
class Ahoy::Store < Ahoy::BaseStore
|
211
|
-
def track_visit(data)
|
212
|
-
post("ahoy_visits", data)
|
213
|
-
end
|
214
|
-
|
215
|
-
def track_event(data)
|
216
|
-
post("ahoy_events", data)
|
217
|
-
end
|
218
|
-
|
219
|
-
def geocode(data)
|
220
|
-
post("ahoy_geocode", data)
|
221
|
-
end
|
222
|
-
|
223
|
-
def authenticate(data)
|
224
|
-
post("ahoy_auth", data)
|
225
|
-
end
|
226
|
-
|
227
|
-
private
|
228
|
-
|
229
|
-
def post(topic, data)
|
230
|
-
client.put_record(
|
231
|
-
delivery_stream_name: topic,
|
232
|
-
record: {data: "#{data.to_json}\n"}
|
233
|
-
)
|
234
|
-
end
|
235
|
-
|
236
|
-
def client
|
237
|
-
@client ||= Aws::Firehose::Client.new
|
238
|
-
end
|
239
|
-
end
|
240
|
-
```
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class Ahoy::Event < <%= rails5? ? "ApplicationRecord" : "ActiveRecord::Base" %>
|
2
|
-
include Ahoy::QueryMethods
|
3
|
-
|
4
|
-
self.table_name = "ahoy_events"
|
5
|
-
|
6
|
-
belongs_to :visit
|
7
|
-
belongs_to :user<%= rails5? ? ", optional: true" : nil %><% if properties_type == "text" %>
|
8
|
-
|
9
|
-
serialize :properties, JSON<% end %>
|
10
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
Mongoid.logger.level = Logger::WARN
|
4
|
-
Mongo::Logger.logger.level = Logger::WARN
|
5
|
-
|
6
|
-
Mongoid.configure do |config|
|
7
|
-
config.connect_to("ahoy_test")
|
8
|
-
end
|
9
|
-
|
10
|
-
class MongoidEvent
|
11
|
-
include Mongoid::Document
|
12
|
-
include Ahoy::QueryMethods
|
13
|
-
|
14
|
-
field :properties, type: Hash
|
15
|
-
end
|
16
|
-
|
17
|
-
class MongoidTest < Minitest::Test
|
18
|
-
include QueryMethodsTest
|
19
|
-
|
20
|
-
def model
|
21
|
-
MongoidEvent
|
22
|
-
end
|
23
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.create_table :mysql_json_events, force: true do |t|
|
6
|
-
t.json :properties
|
7
|
-
end
|
8
|
-
|
9
|
-
class MysqlJsonEvent < MysqlBase
|
10
|
-
end
|
11
|
-
|
12
|
-
class MysqlJsonTest < Minitest::Test
|
13
|
-
include QueryMethodsTest
|
14
|
-
|
15
|
-
def model
|
16
|
-
MysqlJsonEvent
|
17
|
-
end
|
18
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.create_table :mysql_text_events, force: true do |t|
|
6
|
-
t.text :properties
|
7
|
-
end
|
8
|
-
|
9
|
-
class MysqlTextEvent < MysqlBase
|
10
|
-
serialize :properties, JSON
|
11
|
-
end
|
12
|
-
|
13
|
-
class MysqlTextTest < Minitest::Test
|
14
|
-
include QueryMethodsTest
|
15
|
-
|
16
|
-
def model
|
17
|
-
MysqlTextEvent
|
18
|
-
end
|
19
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.enable_extension "hstore"
|
6
|
-
|
7
|
-
ActiveRecord::Migration.create_table :postgresql_hstore_events, force: true do |t|
|
8
|
-
t.hstore :properties
|
9
|
-
end
|
10
|
-
|
11
|
-
class PostgresqlHstoreEvent < PostgresqlBase
|
12
|
-
end
|
13
|
-
|
14
|
-
class PostgresqlHstoreTest < Minitest::Test
|
15
|
-
include QueryMethodsTest
|
16
|
-
|
17
|
-
def model
|
18
|
-
PostgresqlHstoreEvent
|
19
|
-
end
|
20
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.create_table :postgresql_json_events, force: true do |t|
|
6
|
-
t.json :properties
|
7
|
-
end
|
8
|
-
|
9
|
-
class PostgresqlJsonEvent < PostgresqlBase
|
10
|
-
end
|
11
|
-
|
12
|
-
class PostgresqlJsonTest < Minitest::Test
|
13
|
-
include QueryMethodsTest
|
14
|
-
|
15
|
-
def model
|
16
|
-
PostgresqlJsonEvent
|
17
|
-
end
|
18
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.create_table :postgresql_jsonb_events, force: true do |t|
|
6
|
-
t.jsonb :properties
|
7
|
-
t.index :properties, using: 'gin'
|
8
|
-
end
|
9
|
-
|
10
|
-
class PostgresqlJsonbEvent < PostgresqlBase
|
11
|
-
end
|
12
|
-
|
13
|
-
class PostgresqlJsonbTest < Minitest::Test
|
14
|
-
include QueryMethodsTest
|
15
|
-
|
16
|
-
def model
|
17
|
-
PostgresqlJsonbEvent
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
|
4
|
-
|
5
|
-
ActiveRecord::Migration.create_table :postgresql_text_events, force: true do |t|
|
6
|
-
t.text :properties
|
7
|
-
end
|
8
|
-
|
9
|
-
class PostgresqlTextEvent < PostgresqlBase
|
10
|
-
serialize :properties, JSON
|
11
|
-
end
|
12
|
-
|
13
|
-
class PostgresqlTextTest < Minitest::Test
|
14
|
-
include QueryMethodsTest
|
15
|
-
|
16
|
-
def model
|
17
|
-
PostgresqlTextEvent
|
18
|
-
end
|
19
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require "bundler/setup"
|
2
|
-
Bundler.require(:default)
|
3
|
-
require "minitest/autorun"
|
4
|
-
require "minitest/pride"
|
5
|
-
require "active_record"
|
6
|
-
require "mongoid"
|
7
|
-
|
8
|
-
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"]
|
9
|
-
|
10
|
-
class PostgresqlBase < ActiveRecord::Base
|
11
|
-
include Ahoy::QueryMethods
|
12
|
-
establish_connection adapter: "postgresql", database: "ahoy_test"
|
13
|
-
self.abstract_class = true
|
14
|
-
end
|
15
|
-
|
16
|
-
class MysqlBase < ActiveRecord::Base
|
17
|
-
include Ahoy::QueryMethods
|
18
|
-
establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
|
19
|
-
self.abstract_class = true
|
20
|
-
end
|
21
|
-
|
22
|
-
module QueryMethodsTest
|
23
|
-
def setup
|
24
|
-
model.delete_all
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_empty
|
28
|
-
assert_equal 0, count_events({})
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_string
|
32
|
-
create_event value: "world"
|
33
|
-
assert_equal 1, count_events(value: "world")
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_number
|
37
|
-
create_event value: 1
|
38
|
-
assert_equal 1, count_events(value: 1)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_date
|
42
|
-
today = Date.today
|
43
|
-
create_event value: today
|
44
|
-
assert_equal 1, count_events(value: today)
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_time
|
48
|
-
now = Time.now
|
49
|
-
create_event value: now
|
50
|
-
assert_equal 1, count_events(value: now)
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_true
|
54
|
-
create_event value: true
|
55
|
-
assert_equal 1, count_events(value: true)
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_false
|
59
|
-
create_event value: false
|
60
|
-
assert_equal 1, count_events(value: false)
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_nil
|
64
|
-
create_event value: nil
|
65
|
-
assert_equal 1, count_events(value: nil)
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_any
|
69
|
-
create_event hello: "world", prop2: "hi"
|
70
|
-
assert_equal 1, count_events(hello: "world")
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_multiple
|
74
|
-
create_event prop1: "hi", prop2: "bye"
|
75
|
-
assert_equal 1, count_events(prop1: "hi", prop2: "bye")
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_multiple_order
|
79
|
-
create_event prop2: "bye", prop1: "hi"
|
80
|
-
assert_equal 1, count_events(prop1: "hi", prop2: "bye")
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_partial
|
84
|
-
create_event hello: "world"
|
85
|
-
assert_equal 0, count_events(hello: "world", prop2: "hi")
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_prefix
|
89
|
-
create_event value: 123
|
90
|
-
assert_equal 0, count_events(value: 1)
|
91
|
-
end
|
92
|
-
|
93
|
-
def create_event(properties)
|
94
|
-
model.create(properties: properties)
|
95
|
-
end
|
96
|
-
|
97
|
-
def count_events(properties)
|
98
|
-
model.where_properties(properties).count
|
99
|
-
end
|
100
|
-
end
|