fera-api 0.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 +7 -0
- data/.idea/fera-api.iml +86 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.idea/workspace.xml +91 -0
- data/.rspec +3 -0
- data/.rubocop.yml +56 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +92 -0
- data/LICENSE.txt +21 -0
- data/README.md +256 -0
- data/Rakefile +12 -0
- data/lib/fera/api/version.rb +7 -0
- data/lib/fera/api.rb +69 -0
- data/lib/fera/app.rb +33 -0
- data/lib/fera/models/base.rb +374 -0
- data/lib/fera/models/collection.rb +26 -0
- data/lib/fera/models/concerns/belongs_to_customer.rb +70 -0
- data/lib/fera/models/concerns/belongs_to_order.rb +87 -0
- data/lib/fera/models/concerns/belongs_to_product.rb +48 -0
- data/lib/fera/models/concerns/belongs_to_review.rb +40 -0
- data/lib/fera/models/concerns/belongs_to_submission.rb +39 -0
- data/lib/fera/models/concerns/has_many_orders.rb +30 -0
- data/lib/fera/models/concerns/has_many_reviews.rb +30 -0
- data/lib/fera/models/concerns/has_many_submissions.rb +30 -0
- data/lib/fera/models/concerns/has_media.rb +95 -0
- data/lib/fera/models/concerns/has_subject.rb +44 -0
- data/lib/fera/models/customer.rb +8 -0
- data/lib/fera/models/media.rb +55 -0
- data/lib/fera/models/order.rb +5 -0
- data/lib/fera/models/photo.rb +5 -0
- data/lib/fera/models/product.rb +12 -0
- data/lib/fera/models/rating.rb +9 -0
- data/lib/fera/models/review.rb +18 -0
- data/lib/fera/models/store.rb +11 -0
- data/lib/fera/models/submission.rb +19 -0
- data/lib/fera/models/video.rb +5 -0
- data/lib/fera/models/webhook.rb +4 -0
- data/lib/fera.rb +4 -0
- metadata +167 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module BelongsToProduct
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :product, class_name: "Fera::Product"
|
9
|
+
end
|
10
|
+
|
11
|
+
def product=(product)
|
12
|
+
product_id = if product.is_a?(Product)
|
13
|
+
product.id
|
14
|
+
else
|
15
|
+
product.try(:with_indifferent_access).try(:[], :id)
|
16
|
+
end
|
17
|
+
external_product_id = if product.is_a?(Product)
|
18
|
+
product.external_id
|
19
|
+
else
|
20
|
+
product.try(:with_indifferent_access).try(:[], :external_id)
|
21
|
+
end
|
22
|
+
@product = if product.is_a?(Product)
|
23
|
+
product
|
24
|
+
else
|
25
|
+
Product.new(product, product_id.present?)
|
26
|
+
end
|
27
|
+
self.attributes['product_id'] = product_id
|
28
|
+
self.attributes['external_product_id'] = external_product_id
|
29
|
+
self.attributes.delete('product')
|
30
|
+
@product
|
31
|
+
end
|
32
|
+
|
33
|
+
def product
|
34
|
+
if @product.present?
|
35
|
+
@product
|
36
|
+
elsif attributes.key?('product') && attributes['product'].present?
|
37
|
+
Product.new(attributes['product'], true)
|
38
|
+
elsif attributes.key?('product_id') && product_id.present?
|
39
|
+
Product.find(product_id)
|
40
|
+
elsif attributes.key?('external_product_id') && external_product_id.present?
|
41
|
+
Product.find(external_product_id)
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module BelongsToReview
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :review, class_name: "Fera::Review"
|
9
|
+
end
|
10
|
+
|
11
|
+
def review=(review)
|
12
|
+
review_id = if review.is_a?(Review)
|
13
|
+
review.id
|
14
|
+
else
|
15
|
+
review.try(:with_indifferent_access).try(:[], :id)
|
16
|
+
end
|
17
|
+
@review = if review.is_a?(Review)
|
18
|
+
review
|
19
|
+
else
|
20
|
+
Review.new(review, review_id.present?)
|
21
|
+
end
|
22
|
+
self.attributes['review_id'] = review_id
|
23
|
+
self.attributes.delete('review')
|
24
|
+
@review
|
25
|
+
end
|
26
|
+
|
27
|
+
def review
|
28
|
+
if @review.present?
|
29
|
+
@review
|
30
|
+
elsif attributes.key?('review') && attributes['review'].present?
|
31
|
+
Review.new(attributes['review'], true)
|
32
|
+
elsif attributes.key?('review_id') && review_id.present?
|
33
|
+
Review.find(review_id)
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module BelongsToSubmission
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :submission, class_name: "Fera::Submission"
|
9
|
+
end
|
10
|
+
|
11
|
+
def submission=(submission)
|
12
|
+
submission_id = if submission.is_a?(Submission)
|
13
|
+
submission.id
|
14
|
+
else
|
15
|
+
submission.try(:with_indifferent_access).try(:[], :id)
|
16
|
+
end
|
17
|
+
@submission = if submission.is_a?(Submission)
|
18
|
+
submission
|
19
|
+
else
|
20
|
+
Submission.new(submission, submission_id.present?)
|
21
|
+
end
|
22
|
+
self.attributes['submission_id'] = submission_id
|
23
|
+
self.attributes.delete('submission')
|
24
|
+
@submission
|
25
|
+
end
|
26
|
+
|
27
|
+
def submission
|
28
|
+
if @submission.present?
|
29
|
+
@submission
|
30
|
+
elsif attributes.key?('submission') && attributes['submission'].present?
|
31
|
+
Submission.new(attributes['submission'], true)
|
32
|
+
elsif attributes.key?('submission_id') && submission_id.present?
|
33
|
+
Submission.find(submission_id)
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module HasManyOrders
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :orders, class_name: "Fera::Order"
|
9
|
+
end
|
10
|
+
|
11
|
+
def orders=(new_orders)
|
12
|
+
@orders = new_orders.to_a.map do |model|
|
13
|
+
if model.is_a?(Order)
|
14
|
+
model
|
15
|
+
else
|
16
|
+
model_id = model.try(:with_indifferent_access).try(:[], :id)
|
17
|
+
Order.new(model, model_id.present?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def photos(query = {})
|
23
|
+
if @orders && query.blank?
|
24
|
+
@orders.to_a
|
25
|
+
else
|
26
|
+
Order.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module HasManyReviews
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :reviews, class_name: "Fera::Review"
|
9
|
+
end
|
10
|
+
|
11
|
+
def reviews=(new_reviews)
|
12
|
+
@reviews = new_reviews.to_a.map do |model|
|
13
|
+
if model.is_a?(Review)
|
14
|
+
model
|
15
|
+
else
|
16
|
+
model_id = model.try(:with_indifferent_access).try(:[], :id)
|
17
|
+
Review.new(model, model_id.present?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def reviews(query = {})
|
23
|
+
if @reviews && query.blank?
|
24
|
+
@reviews.to_a
|
25
|
+
else
|
26
|
+
Review.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module HasManySubmissions
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :submission, class_name: "Fera::Submission"
|
9
|
+
end
|
10
|
+
|
11
|
+
def submissions=(new_submissions)
|
12
|
+
@submissions = new_submissions.to_a.map do |model|
|
13
|
+
if model.is_a?(Submission)
|
14
|
+
model
|
15
|
+
else
|
16
|
+
model_id = model.try(:with_indifferent_access).try(:[], :id)
|
17
|
+
Submission.new(model, model_id.present?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def submissions(query = {})
|
23
|
+
if @submissions && query.blank?
|
24
|
+
@submissions.to_a
|
25
|
+
else
|
26
|
+
Submission.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module HasMedia
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :media, class_name: "Fera::Media"
|
9
|
+
has_many :videos, class_name: "Fera::Video"
|
10
|
+
has_many :photos, class_name: "Fera::Photo"
|
11
|
+
end
|
12
|
+
|
13
|
+
def media=(inputs)
|
14
|
+
@media = inputs.to_a.map do |input|
|
15
|
+
self.new_media(input)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_media(input)
|
20
|
+
new_model = self.new_media(input)
|
21
|
+
if @media.nil?
|
22
|
+
@media = [new_model]
|
23
|
+
else
|
24
|
+
@media << new_model
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def new_media(input = nil)
|
29
|
+
model_class = [Photo, Video].include?(input.class) ? input.class : Media
|
30
|
+
new_has_many_associated_model(model_class, input)
|
31
|
+
end
|
32
|
+
|
33
|
+
def media(query = {})
|
34
|
+
if @media && query.blank?
|
35
|
+
@media.to_a
|
36
|
+
else
|
37
|
+
Media.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def photos=(inputs)
|
42
|
+
@photos = inputs.to_a.map do |input|
|
43
|
+
new_has_many_associated_model(Photo, input)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_photo(input)
|
48
|
+
new_model = self.new_photo(input)
|
49
|
+
if @photos.nil?
|
50
|
+
@photos = [new_model]
|
51
|
+
else
|
52
|
+
@photos << new_model
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def new_photo(input = nil)
|
57
|
+
new_has_many_associated_model(Photo, input)
|
58
|
+
end
|
59
|
+
|
60
|
+
def photos(query = {})
|
61
|
+
if @photos && query.blank?
|
62
|
+
@photos.to_a
|
63
|
+
else
|
64
|
+
Photo.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def videos=(inputs)
|
69
|
+
@videos = inputs.to_a.map do |input|
|
70
|
+
self.new_video(input)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_video(input)
|
75
|
+
new_model = self.new_video(input)
|
76
|
+
if @videos.nil?
|
77
|
+
@videos = [new_model]
|
78
|
+
else
|
79
|
+
@videos << new_model
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def new_video(input = nil)
|
84
|
+
new_has_many_associated_model(Video, input)
|
85
|
+
end
|
86
|
+
|
87
|
+
def videos(query = {})
|
88
|
+
if @videos && query.blank?
|
89
|
+
@videos.to_a
|
90
|
+
else
|
91
|
+
Video.where(query.merge("#{ self.class.name.demodulize.underscore }_id" => id))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fera
|
4
|
+
module HasSubject
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def for_products(product_ids = nil)
|
9
|
+
if product_ids.present?
|
10
|
+
where(product_id: product_ids)
|
11
|
+
else
|
12
|
+
where(subject: :product)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def for_product(product_id)
|
17
|
+
for_products(product_id).try(:first)
|
18
|
+
end
|
19
|
+
|
20
|
+
def for_store
|
21
|
+
all.where(subject: :store).try(:first)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns the associated product model if it was preloaded in the original request and if the object is for a product.
|
27
|
+
# @return [::Fera::Product, NilClass]
|
28
|
+
def product
|
29
|
+
if attributes['subject'] =~ /^product/i
|
30
|
+
super
|
31
|
+
else
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def for_product?
|
37
|
+
subject.to_s == 'product'
|
38
|
+
end
|
39
|
+
|
40
|
+
def for_store?
|
41
|
+
subject.to_s == 'store'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fera
|
2
|
+
class Media < Base
|
3
|
+
include HasSubject
|
4
|
+
include BelongsToCustomer
|
5
|
+
include BelongsToProduct
|
6
|
+
include BelongsToReview
|
7
|
+
include BelongsToSubmission
|
8
|
+
|
9
|
+
after_create :remove_file_param
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def instantiate_record(record, prefix_options = {})
|
13
|
+
new_klass = if record['type'] == 'video'
|
14
|
+
Video
|
15
|
+
else
|
16
|
+
Photo
|
17
|
+
end
|
18
|
+
new_klass.new(record, record['id'].present?).tap do |resource|
|
19
|
+
resource.prefix_options = prefix_options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_video?
|
25
|
+
type.to_s == 'video'
|
26
|
+
end
|
27
|
+
alias_method :video?, :is_video?
|
28
|
+
|
29
|
+
def is_photo?
|
30
|
+
type.to_s == 'photo'
|
31
|
+
end
|
32
|
+
alias_method :photo?, :is_photo?
|
33
|
+
|
34
|
+
def file=(f)
|
35
|
+
if f.is_a?(File)
|
36
|
+
file_name = File.basename(f.path)
|
37
|
+
mime_type_group = type == 'video' ? 'video' : 'image'
|
38
|
+
self.attributes['file'] = {
|
39
|
+
'name' => File.basename(file_name),
|
40
|
+
'data' => "data:#{ mime_type_group }/#{ file_name.split('.').last };base64,#{ Base64.encode64(f.read) }"
|
41
|
+
}
|
42
|
+
else
|
43
|
+
self.attributes['file'] = f
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def remove_file_param
|
50
|
+
if self.attributes.key?('file')
|
51
|
+
self.attributes.delete('file')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fera
|
2
|
+
class Review < Base
|
3
|
+
include HasMedia
|
4
|
+
include HasSubject
|
5
|
+
include BelongsToCustomer
|
6
|
+
include BelongsToProduct
|
7
|
+
include BelongsToSubmission
|
8
|
+
|
9
|
+
def only_rating?
|
10
|
+
body.blank? && heading.blank?
|
11
|
+
end
|
12
|
+
alias_method :rating_only?, :only_rating?
|
13
|
+
|
14
|
+
def stars
|
15
|
+
(('★' * rating) + ('☆' * (5 - rating))).chars.join(" ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fera
|
2
|
+
class Submission < Base
|
3
|
+
include HasMedia
|
4
|
+
include HasManyReviews
|
5
|
+
include BelongsToCustomer
|
6
|
+
include BelongsToOrder
|
7
|
+
|
8
|
+
schema do
|
9
|
+
string 'id'
|
10
|
+
string 'external_customer_id'
|
11
|
+
string 'customer_id'
|
12
|
+
|
13
|
+
boolean 'is_test'
|
14
|
+
|
15
|
+
timestamp 'created_at'
|
16
|
+
timestamp 'updated_at'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/fera.rb
ADDED