apisync-rails 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 88abcef0b707a5935bc1c96d7ed9590a40d1b925
4
- data.tar.gz: b9f0d57c8b2ce5529cb0bb2c3e0f078e0d761a56
3
+ metadata.gz: 38f143e80f7eeefc8f80b710b319435f7fc6c0bf
4
+ data.tar.gz: c7f569963767bc579f2545de3ab68bf6b25900ac
5
5
  SHA512:
6
- metadata.gz: a68e29abe9082c255baf4aaf44b5b9842cc86ea59d8c37b251385c0a72ed8a30bac5b824e3740d7a134030372c3a16e153fd96e2977d6bc6b878857eeb7a9fb5
7
- data.tar.gz: fa4fea27b22ef896a08171640f7346ac19488eca67d305dccdb9d9b1244a1c0081ec63baaafd46ace67e415da358cd888822eddac13de99eca201ad68674aef6
6
+ metadata.gz: cb369dff486a556acfd6de4ed212a60c06bdf545b73eeed32969caf8a8e49246e1c5463d4ad3010b53b628d3da17d9d2ee0ae1fdb7f42a2c0ee376b85dd8b155
7
+ data.tar.gz: 75eaa44a224a335a72b94c484ea09feca8a1ebfad2f8647c2d74cf4a31d9a05b645e401a77a4e859e2e77aeeba77e37ae168b8863759e690993a268d3ab0af6e
data/.gitignore CHANGED
@@ -12,3 +12,6 @@
12
12
  .rspec_status
13
13
 
14
14
  *.gem
15
+ spec/test_app/db/*.sqlite*
16
+ spec/test_app/log
17
+ spec/test_app/tmp
data/Gemfile CHANGED
@@ -1,6 +1,9 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in apisync-rails.gemspec
6
6
  gemspec
7
+
8
+ # For development
9
+ # gem "apisync", path: "./../apisync-ruby", group: :development
data/README.md CHANGED
@@ -1,4 +1,15 @@
1
- # Apisync::Rails
1
+ # apisync-rails
2
+
3
+ This gem gives you the tools to keep your product models synchronized with
4
+ ApiSync.
5
+
6
+ * **DSL:** built-in DSL for ActiveRecord models that pushes your data
7
+ automatically to apisync.io.
8
+ * **Sidekiq:** when Sidekiq is present, this gem will push data asynchronously.
9
+ Otherwise, it will fallback to pushing data synchronously.
10
+
11
+ If you're not using Rails with ActiveRecord, please use
12
+ [apisync-ruby](https://github.com/apisync/apisync-ruby) instead.
2
13
 
3
14
  ## Installation
4
15
 
@@ -14,6 +25,106 @@ And then execute:
14
25
 
15
26
  ## Usage
16
27
 
28
+ **Step 1: API Key:** in `config/initializers/apisync.rb`, define your
29
+ key:
30
+
31
+ ```ruby
32
+ Apisync.api_key = ENV["APISYNC_API_KEY"];
33
+ ```
34
+
35
+ **Step 2: setup your models:** you need to define which attributes in your
36
+ product models map to the attributes in ApiSync.
37
+
38
+ Some attributes are required. See
39
+ the [API reference](https://docs.apisync.io/api/) for details.
40
+
41
+ ```ruby
42
+ class Product < ActiveRecord::Base
43
+ apisync do
44
+ # required attributes
45
+ attribute :ad_template_type, from: :category
46
+ attribute :available, from: :active?
47
+ attribute :content_language, value: "pt-br"
48
+
49
+ # recommended attributes
50
+ attribute :brand, from: :manufacturer
51
+ attribute :condition, from: :normalize_condition
52
+ attribute :description
53
+ attribute :images
54
+ attribute :link
55
+ attribute :model
56
+ attribute :price
57
+ attribute :reference_id, from: :id # optional, defaults to :id
58
+ attribute :title
59
+ attribute :year
60
+
61
+ # these are other attributes that you can send
62
+ custom_attribute :city, name: :city_attr_name
63
+ end
64
+
65
+ private
66
+
67
+ # required format (see reference docs)
68
+ def images
69
+ [{
70
+ uri: "https://page.com/image1.jpg",
71
+ order: 1
72
+ }, {
73
+ uri: "https://page.com/image2.jpg",
74
+ order: 2
75
+ }]
76
+ end
77
+
78
+ # required format (see reference docs)
79
+ def price
80
+ {
81
+ amount: 1234, # equivalent to R$12,34
82
+ currency: "BRL"
83
+ }
84
+ end
85
+
86
+ # these give a human name to the custom attributes,
87
+ # called based on :name parameters
88
+ def city_attr_name
89
+ "Delivery city"
90
+ end
91
+ end
92
+ ```
93
+
94
+ **Explanation**
95
+
96
+ **attribute** specifies one value to be sent to ApiSync. Pass the
97
+ attribute name as parameter, e.g `attribute :brand`.
98
+
99
+ **from** specifies what method has the values for the
100
+ respective attribute. If you leave it blank then we'll default to the attribute
101
+ name, e.g `attribute :brand` will call `def brand` whereas `attribute :brand, from:
102
+ :manufacturer` will call `def manufacturer`.
103
+
104
+ **value** specifies a value for the respective attribute. Ideal for values that
105
+ don't change.
106
+
107
+ **custom_attribute** allows you to specify an attribute that is not part
108
+ of the documentation. You can use these to create richer ad templates.
109
+
110
+ ### Reference ID
111
+
112
+ The **reference_id** attribute is extremely important. We use the attribute to
113
+ keep track of the record's state. The first time a record is sent, ApiSync
114
+ creates it and saves the reference id. The second time a record is sent it
115
+ knows that it only needs to be updated, not created.
116
+ If you omit `reference_id`, we will keep creating the same record
117
+ over and over.
118
+
119
+ By default, `reference_id` is set to whatever **id** value is. You can
120
+ customize it, e.g `attribute :reference_id, from: :my_custom_id`.
121
+
122
+ ### Note on callbacks
123
+
124
+ This gem uses Rails' callbacks to trigger synchronization.
125
+ If you're bypassing methods like `after_commit`,
126
+ no data will be sent to ApiSync. For example, `update_attribute` doesn't
127
+ perform validations checks, so please use `update_attributes` instead.
17
128
 
18
129
  ## Development
19
130
 
@@ -23,7 +134,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
23
134
 
24
135
  ## Contributing
25
136
 
26
- Bug reports and pull requests are welcome on GitHub at https://github.com/kurko/apisync-rails.
137
+ Bug reports and pull requests are welcome on GitHub at https://github.com/apisync/apisync-rails.
27
138
 
28
139
  ## License
29
140
 
@@ -21,7 +21,18 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
+ spec.add_dependency "activesupport", ">= 4.2"
25
+ spec.add_dependency "activerecord", ">= 4.2"
26
+ # in dev mode
27
+ spec.add_dependency "apisync"
28
+
24
29
  spec.add_development_dependency "bundler", "~> 1.15"
25
30
  spec.add_development_dependency "rake", "~> 10.0"
26
31
  spec.add_development_dependency "rspec", "~> 3.5"
32
+ spec.add_development_dependency "rails", "~> 5.0"
33
+ spec.add_development_dependency "sqlite3"
34
+ spec.add_development_dependency "awesome_print"
35
+ spec.add_development_dependency "database_cleaner"
36
+ spec.add_development_dependency "webmock"
37
+ spec.add_development_dependency "pry"
27
38
  end
@@ -0,0 +1,41 @@
1
+ class Apisync
2
+ module ActiveRecordExtension
3
+ def self.included(klass)
4
+ klass.extend(ClassMethods)
5
+ klass.include(InstanceMethods)
6
+ end
7
+
8
+ module InstanceMethods
9
+ attr_accessor :apisync
10
+
11
+ private
12
+
13
+ def start_apisync
14
+ @apisync = Apisync::Rails::Model.new(self)
15
+ @apisync.instance_eval(&self.class.apisync_block)
16
+ @apisync.validate!
17
+ end
18
+
19
+ def save_to_apisync
20
+ @apisync.sync
21
+ end
22
+ end
23
+
24
+ module ClassMethods
25
+ def apisync_block
26
+ @apisync_block
27
+ end
28
+
29
+ def apisync(&block)
30
+ after_initialize :start_apisync
31
+ after_commit :save_to_apisync
32
+
33
+ @apisync_block = block
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ ActiveSupport.on_load(:active_record) do
40
+ ::ActiveRecord::Base.send(:include, Apisync::ActiveRecordExtension)
41
+ end
data/lib/apisync/rails.rb CHANGED
@@ -1,6 +1,13 @@
1
+ require "bundler/setup"
2
+
3
+ require "active_support"
4
+ require "apisync"
1
5
  require "apisync/rails/version"
6
+ require "apisync/rails/model"
7
+ require "apisync/rails/http"
8
+ require "apisync/active_record_extension"
2
9
 
3
- module Apisync
10
+ class Apisync
4
11
  module Rails
5
12
  # Your code goes here...
6
13
  end
@@ -0,0 +1,10 @@
1
+ class Apisync
2
+ module Rails
3
+ class Http
4
+ def self.post(attrs)
5
+ client = Apisync.new
6
+ client.inventory_items.save(attributes: attrs)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,86 @@
1
+ class Apisync
2
+ module Rails
3
+ class Model
4
+ class MissingAttribute < StandardError; end
5
+
6
+ REQUIRED_ATTRS = {
7
+ available: "This is required to enable/disable your item in our database.",
8
+ content_language: "This is required to show your item to the correct audience.",
9
+ ad_template_type: "This is required to generate the correct ads for this item."
10
+ }.freeze
11
+
12
+ WARNING_ATTRS = {
13
+ reference_id: "This is required to track your record, otherwise it will be created every time."
14
+ }
15
+
16
+ attr_reader :attributes
17
+
18
+ def initialize(model)
19
+ @model = model
20
+ @attributes = {}
21
+ end
22
+
23
+ def attribute(attr_name, from: nil, value: nil)
24
+ @attributes.delete(attr_name)
25
+ @attributes[attr_name] = attr_value(attr_name, from: from, value: value)
26
+ end
27
+
28
+ def custom_attribute(attr_name, from: nil, value: nil, name: nil)
29
+ @attributes[:custom_attributes] ||= []
30
+ @attributes[:custom_attributes] << {
31
+ name: localized_name(name),
32
+ identifier: attr_name.to_s,
33
+ value: attr_value(attr_name, from: from, value: value)
34
+ }
35
+ end
36
+
37
+ def sync
38
+ set_reference_id
39
+ validate!
40
+ log_warnings
41
+ Apisync::Rails::Http.post(@attributes)
42
+ end
43
+
44
+ def validate!
45
+ REQUIRED_ATTRS.each do |attr, message|
46
+ if @attributes[attr].blank?
47
+ raise MissingAttribute, "Please specify #{attr}. #{message}"
48
+ end
49
+ end
50
+ end
51
+
52
+ def log_warnings
53
+ WARNING_ATTRS.each do |attr, message|
54
+ if @attributes[attr].blank?
55
+ ::Rails.logger.warn "Please specify #{attr}. #{message}"
56
+ end
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def set_reference_id
63
+ if @attributes[:reference_id].blank? && @model.id.present?
64
+ @attributes[:reference_id] = @model.id.to_s
65
+ end
66
+ end
67
+
68
+ def attr_value(attr_name, from:, value:)
69
+ if value.blank?
70
+ if from.present?
71
+ value = @model.send(from)
72
+ else
73
+ value = @model.send(attr_name)
74
+ end
75
+ end
76
+ value
77
+ end
78
+
79
+ def localized_name(name)
80
+ if name.present?
81
+ @model.send(name)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,5 +1,5 @@
1
- module Apisync
1
+ class Apisync
2
2
  module Rails
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apisync-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre de Oliveira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-08 00:00:00.000000000 Z
11
+ date: 2017-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: apisync
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  - !ruby/object:Gem::Dependency
14
56
  name: bundler
15
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +94,90 @@ dependencies:
52
94
  - - "~>"
53
95
  - !ruby/object:Gem::Version
54
96
  version: '3.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sqlite3
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: awesome_print
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: database_cleaner
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
55
181
  description: Use this gem if you're using Rails. If you're not using Rails, then use
56
182
  apisync-ruby gem.
57
183
  email:
@@ -72,7 +198,10 @@ files:
72
198
  - apisync-rails.gemspec
73
199
  - bin/console
74
200
  - bin/setup
201
+ - lib/apisync/active_record_extension.rb
75
202
  - lib/apisync/rails.rb
203
+ - lib/apisync/rails/http.rb
204
+ - lib/apisync/rails/model.rb
76
205
  - lib/apisync/rails/version.rb
77
206
  homepage: https://github.com/apisync/apisync-rails
78
207
  licenses: