constructorio 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/constructorio.rb +79 -32
- data/lib/constructorio/fields.rb +3 -3
- data/lib/constructorio/version.rb +1 -1
- data/test/constructorio_test.rb +68 -10
- data/test/test_helper.rb +15 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0afa62571df5734cb0bec7f26976b1ff8b4ed039
|
4
|
+
data.tar.gz: 8bfbffbaee6ff520ec59a6d5208ef3fd5dba5b7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 479bdfc0a8a29dfbcb15254af5f36a88438db4763f53d5ccbaa3a67cd5af066ac9f673483b154e36e788b9f47daa4f3e093b36a4dece7e899dd0581804f9db8b
|
7
|
+
data.tar.gz: cfeca1527e5c9f1d543e38a514e41e02310c5a181d9e11c29effcbd288d1a68fb8c2a85468317ebf7efe2fcb8778927518c3a99fb893069b600fd3e8d5ab29b6
|
data/README.md
CHANGED
data/lib/constructorio.rb
CHANGED
@@ -13,7 +13,10 @@ begin
|
|
13
13
|
rescue LoadError
|
14
14
|
end
|
15
15
|
|
16
|
+
class MissingItemName < StandardError; end
|
17
|
+
|
16
18
|
module ConstructorIO
|
19
|
+
|
17
20
|
class << self
|
18
21
|
attr_accessor :configuration
|
19
22
|
end
|
@@ -26,50 +29,94 @@ module ConstructorIO
|
|
26
29
|
yield(configuration)
|
27
30
|
end
|
28
31
|
|
29
|
-
|
32
|
+
# This injects the methods on the included hook
|
33
|
+
def self.included base
|
34
|
+
base.send :include, InstanceMethods
|
35
|
+
base.extend ClassMethods
|
36
|
+
end
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
module ClassMethods
|
39
|
+
# "fields" is expected to be an array of strings or an array of hashes, like:
|
40
|
+
# "product_name", "description"
|
41
|
+
# - or -
|
42
|
+
# { 'attribute' => 'product_name', 'metadata' => { metadata_one => ->{ something_dynamic }} }
|
43
|
+
def autocomplete(fields, autocomplete_key = ConstructorIO.configuration.autocomplete_key)
|
44
|
+
# All fields require an attribute
|
45
|
+
field_names = fields.map { |f| f.is_a?(String) ? f : f['attribute'] }
|
46
|
+
raise MissingItemName if field_names.include? nil
|
34
47
|
|
35
|
-
|
36
|
-
|
37
|
-
updated_fields.each do |field|
|
38
|
-
record.class.send(:add_record, record[field.to_sym], autocomplete_key)
|
48
|
+
field_names.each do |field|
|
49
|
+
ConstructorIO::Fields.instance.add(self.model_name, field)
|
39
50
|
end
|
40
|
-
end
|
41
51
|
|
42
|
-
|
52
|
+
# transform the data
|
53
|
+
transformed = {}
|
43
54
|
fields.each do |field|
|
44
|
-
|
55
|
+
if field.is_a?(String)
|
56
|
+
transformed[field] = {}
|
57
|
+
else
|
58
|
+
transformed[field['attribute']] = field['metadata']
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
after_save do |record|
|
63
|
+
updated_fields = record.changed.select { |c| field_names.include? c }
|
64
|
+
updated_fields.each do |field|
|
65
|
+
record.send(:constructorio_add_record, record[field.to_sym], transformed[field], autocomplete_key)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
before_destroy do |record|
|
70
|
+
field_names.each do |field|
|
71
|
+
record.send(:constructorio_delete_record, record[field.to_sym], transformed[field], autocomplete_key)
|
72
|
+
end
|
45
73
|
end
|
46
74
|
end
|
47
75
|
end
|
48
76
|
|
49
|
-
|
50
|
-
|
51
|
-
|
77
|
+
module InstanceMethods
|
78
|
+
def constructorio_add_record(value, metadata = {}, autocomplete_key)
|
79
|
+
constructorio_call_api("post", value, metadata, autocomplete_key)
|
80
|
+
end
|
52
81
|
|
53
|
-
|
54
|
-
|
55
|
-
|
82
|
+
def constructorio_delete_record(value, metadata = {}, autocomplete_key)
|
83
|
+
constructorio_call_api("delete", value, metadata, autocomplete_key)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def constructorio_make_request_body(value, metadata)
|
89
|
+
request_body = { "item_name" => "#{value}" }
|
90
|
+
unless metadata.empty?
|
91
|
+
metadata.each do |k, v|
|
92
|
+
v = instance_exec(&v) if v.is_a? Proc
|
93
|
+
request_body[k] = v
|
94
|
+
end
|
95
|
+
end
|
96
|
+
request_body
|
97
|
+
end
|
98
|
+
|
99
|
+
def constructorio_call_api(method, value, metadata, autocomplete_key)
|
100
|
+
api_token = ConstructorIO.configuration.api_token
|
101
|
+
api_url = ConstructorIO.configuration.api_url || "https://ac.constructor.io/"
|
102
|
+
@http_client ||= Faraday.new(url: api_url)
|
103
|
+
@http_client.basic_auth(api_token, '')
|
56
104
|
|
57
|
-
|
58
|
-
|
59
|
-
def call_api(method, value, autocomplete_key)
|
60
|
-
@api_token = ConstructorIO.configuration.api_token
|
61
|
-
@api_url = ConstructorIO.configuration.api_url || "https://ac.constructor.io/"
|
62
|
-
@http_client ||= Faraday.new(url: @api_url)
|
63
|
-
@http_client.basic_auth(@api_token, '')
|
64
|
-
response = @http_client.send(method) do |request|
|
65
|
-
request.url "/v1/item?autocomplete_key=#{autocomplete_key}"
|
66
|
-
request.headers['Content-Type'] = 'application/json'
|
67
|
-
request.body = %Q|{"item_name": "#{value}"}|
|
105
|
+
request_body = constructorio_make_request_body(value, metadata)
|
106
|
+
constructorio_send_request(method, @http_client, request_body, autocomplete_key)
|
68
107
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
108
|
+
|
109
|
+
def constructorio_send_request(method, http_client, request_body, autocomplete_key)
|
110
|
+
response = http_client.send(method) do |request|
|
111
|
+
request.url "/v1/item?autocomplete_key=#{autocomplete_key}"
|
112
|
+
request.headers['Content-Type'] = 'application/json'
|
113
|
+
request.body = request_body.to_json
|
114
|
+
end
|
115
|
+
if response.status.to_s =~ /^2/
|
116
|
+
return nil
|
117
|
+
else
|
118
|
+
return response.status
|
119
|
+
end
|
73
120
|
end
|
74
121
|
end
|
75
122
|
end
|
data/lib/constructorio/fields.rb
CHANGED
data/test/constructorio_test.rb
CHANGED
@@ -1,48 +1,106 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
3
|
class ConstructorIOTest < MiniTest::Test
|
4
|
-
def
|
4
|
+
def test_add_record_makes_request
|
5
5
|
person = Person.new(
|
6
6
|
first_name: "Steven",
|
7
7
|
last_name: "Lai",
|
8
8
|
address: "New York"
|
9
9
|
)
|
10
|
-
Person.expects(:call_api).with("post", "Steven", "person_autocomplete_key")
|
11
10
|
|
11
|
+
person.stubs(:constructorio_send_request)
|
12
|
+
|
13
|
+
person.expects(:constructorio_make_request_body)
|
14
|
+
assert person.save
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_add_simple_record_makes_request
|
18
|
+
person = PersonSimple.new(
|
19
|
+
first_name: "Steven",
|
20
|
+
last_name: "Lai",
|
21
|
+
address: "New York"
|
22
|
+
)
|
23
|
+
|
24
|
+
person.stubs(:constructorio_send_request)
|
25
|
+
|
26
|
+
person.expects(:constructorio_make_request_body)
|
27
|
+
assert person.save
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_add_record_accepts_procs
|
31
|
+
person = Person.new(
|
32
|
+
first_name: "Steven",
|
33
|
+
last_name: "Lai",
|
34
|
+
address: "New York"
|
35
|
+
)
|
36
|
+
|
37
|
+
person.expects(:constructorio_send_request).with(
|
38
|
+
'post',
|
39
|
+
instance_of(Faraday::Connection),
|
40
|
+
{'item_name' => 'Steven', 'test_metadata' => 'test_values', 'test_proc' => 'NEW YORK'},
|
41
|
+
'person_autocomplete_key'
|
42
|
+
)
|
43
|
+
assert person.save
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_add_simple_record_accepts_procs
|
47
|
+
person = PersonSimple.new(
|
48
|
+
first_name: "Steven",
|
49
|
+
last_name: "Lai",
|
50
|
+
address: "New York"
|
51
|
+
)
|
52
|
+
|
53
|
+
person.expects(:constructorio_send_request).with(
|
54
|
+
'post',
|
55
|
+
instance_of(Faraday::Connection),
|
56
|
+
{'item_name' => 'Steven'},
|
57
|
+
'example_autocomplete_key'
|
58
|
+
)
|
59
|
+
assert person.save
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_add_record_sends_request
|
63
|
+
person = Person.new(
|
64
|
+
first_name: "Steven",
|
65
|
+
last_name: "Lai",
|
66
|
+
address: "New York"
|
67
|
+
)
|
68
|
+
|
69
|
+
person.expects(:constructorio_send_request)
|
12
70
|
assert person.save
|
13
71
|
end
|
14
72
|
|
15
|
-
def
|
16
|
-
Person.
|
73
|
+
def test_delete_record_makes_request
|
74
|
+
Person.any_instance.stubs(:constructorio_call_api)
|
17
75
|
person = Person.create(
|
18
76
|
first_name: "Ronald",
|
19
77
|
last_name: "McDonald",
|
20
78
|
address: "Disneyland"
|
21
79
|
)
|
22
80
|
|
23
|
-
|
81
|
+
person.expects(:constructorio_call_api).with("delete", "Ronald", has_entry('test_proc', instance_of(Proc)),"person_autocomplete_key")
|
24
82
|
person.destroy
|
25
83
|
end
|
26
84
|
|
27
|
-
def
|
85
|
+
def test_add_record_without_key_uses_default_key
|
28
86
|
person = PersonNoKey.new(
|
29
87
|
first_name: "Steven",
|
30
88
|
last_name: "Lai",
|
31
89
|
address: "New York"
|
32
90
|
)
|
33
91
|
|
34
|
-
|
92
|
+
person.expects(:constructorio_call_api).with("post", "Lai", anything, ConstructorIO.configuration.autocomplete_key)
|
35
93
|
assert person.save
|
36
94
|
end
|
37
95
|
|
38
|
-
def
|
39
|
-
Person.expects(:
|
96
|
+
def test_fields_are_tracked
|
97
|
+
Person.any_instance.expects(:constructorio_call_api).with("post", "Ronald", anything, "person_autocomplete_key")
|
40
98
|
person = Person.create(
|
41
99
|
first_name: "Ronald",
|
42
100
|
last_name: "McDonald",
|
43
101
|
address: "Disneyland"
|
44
102
|
)
|
45
103
|
|
46
|
-
assert_equal ConstructorIO::Fields.instance.list(
|
104
|
+
assert_equal ConstructorIO::Fields.instance.list('Person'), ["first_name"]
|
47
105
|
end
|
48
106
|
end
|
data/test/test_helper.rb
CHANGED
@@ -24,17 +24,26 @@ ConstructorIO.configure do |config|
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class Person < ActiveRecord::Base
|
27
|
-
|
27
|
+
include ConstructorIO
|
28
|
+
autocomplete [{
|
29
|
+
'attribute' => 'first_name',
|
30
|
+
'metadata' => {
|
31
|
+
'test_metadata' => 'test_values',
|
32
|
+
'test_proc' => ->{ self.address.upcase }
|
33
|
+
}
|
34
|
+
}], "person_autocomplete_key"
|
35
|
+
end
|
28
36
|
|
29
|
-
|
37
|
+
class PersonSimple < ActiveRecord::Base
|
38
|
+
self.table_name = 'people'
|
39
|
+
include ConstructorIO
|
40
|
+
autocomplete [ 'first_name' ]
|
30
41
|
end
|
31
42
|
|
32
43
|
class PersonNoKey < ActiveRecord::Base
|
33
44
|
self.table_name = 'people'
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
autocomplete ['last_name']
|
45
|
+
include ConstructorIO
|
46
|
+
autocomplete [{'attribute' => 'last_name'}]
|
38
47
|
end
|
39
48
|
|
40
49
|
class FakeView
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: constructorio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Lai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|