barkibu-kb 0.16.1

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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +3 -0
  3. data/.gitignore +20 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +45 -0
  6. data/.ruby-version +2 -0
  7. data/.travis.yml +7 -0
  8. data/CHANGELOG.md +185 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile +7 -0
  11. data/Gemfile.lock +182 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +243 -0
  14. data/Rakefile +28 -0
  15. data/barkibu-kb-fake.gemspec +41 -0
  16. data/barkibu-kb.gemspec +54 -0
  17. data/bin/console +14 -0
  18. data/bin/setup +8 -0
  19. data/docker-compose.yaml +15 -0
  20. data/lib/barkibu-kb-fake.rb +1 -0
  21. data/lib/barkibu-kb.rb +33 -0
  22. data/lib/kb/cache.rb +23 -0
  23. data/lib/kb/client.rb +85 -0
  24. data/lib/kb/client_resolver.rb +62 -0
  25. data/lib/kb/concerns/as_kb_wrapper.rb +67 -0
  26. data/lib/kb/concerns.rb +1 -0
  27. data/lib/kb/errors/client_error.rb +9 -0
  28. data/lib/kb/errors/conflict_error.rb +3 -0
  29. data/lib/kb/errors/error.rb +26 -0
  30. data/lib/kb/errors/resource_not_found.rb +3 -0
  31. data/lib/kb/errors/unprocessable_entity_error.rb +3 -0
  32. data/lib/kb/errors.rb +6 -0
  33. data/lib/kb/fake/api.rb +72 -0
  34. data/lib/kb/fake/bounded_context/pet_family/breeds.rb +15 -0
  35. data/lib/kb/fake/bounded_context/pet_family/hubspot_relationship.rb +17 -0
  36. data/lib/kb/fake/bounded_context/pet_family/pet_contracts.rb +24 -0
  37. data/lib/kb/fake/bounded_context/pet_family/pet_parents.rb +98 -0
  38. data/lib/kb/fake/bounded_context/pet_family/pets.rb +84 -0
  39. data/lib/kb/fake/bounded_context/pet_family/products.rb +28 -0
  40. data/lib/kb/fake/bounded_context/rest_resource.rb +134 -0
  41. data/lib/kb/fake.rb +6 -0
  42. data/lib/kb/inflections.rb +3 -0
  43. data/lib/kb/models/assessment.rb +58 -0
  44. data/lib/kb/models/base_model.rb +40 -0
  45. data/lib/kb/models/breed.rb +39 -0
  46. data/lib/kb/models/concerns/creatable.rb +18 -0
  47. data/lib/kb/models/concerns/destroyable.rb +17 -0
  48. data/lib/kb/models/concerns/find_or_creatable.rb +19 -0
  49. data/lib/kb/models/concerns/findable.rb +19 -0
  50. data/lib/kb/models/concerns/inspectionable.rb +13 -0
  51. data/lib/kb/models/concerns/listable.rb +21 -0
  52. data/lib/kb/models/concerns/queryable.rb +34 -0
  53. data/lib/kb/models/concerns/updatable.rb +18 -0
  54. data/lib/kb/models/concerns/upsertable.rb +17 -0
  55. data/lib/kb/models/concerns.rb +10 -0
  56. data/lib/kb/models/condition.rb +32 -0
  57. data/lib/kb/models/hubspot_relationship.rb +34 -0
  58. data/lib/kb/models/pet.rb +68 -0
  59. data/lib/kb/models/pet_contract.rb +77 -0
  60. data/lib/kb/models/pet_parent.rb +111 -0
  61. data/lib/kb/models/plan.rb +44 -0
  62. data/lib/kb/models/product.rb +34 -0
  63. data/lib/kb/models/symptom.rb +25 -0
  64. data/lib/kb/models.rb +15 -0
  65. data/lib/kb/type/array_of_conditions_type.rb +13 -0
  66. data/lib/kb/type/array_of_strings_type.rb +9 -0
  67. data/lib/kb/type/array_of_symptoms_type.rb +13 -0
  68. data/lib/kb/types.rb +7 -0
  69. data/lib/kb/validators/uniqueness_validator.rb +26 -0
  70. data/lib/kb/validators.rb +1 -0
  71. data/lib/kb/version.rb +3 -0
  72. metadata +325 -0
@@ -0,0 +1,18 @@
1
+ module KB
2
+ module Creatable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def create(attributes)
11
+ api_response = kb_client.create attributes
12
+ attributes_from_response(api_response)
13
+ rescue Faraday::Error => e
14
+ raise KB::Error.from_faraday(e)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module KB
2
+ module Destroyable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def destroy(key)
11
+ kb_client.destroy(key)
12
+ rescue Faraday::Error => e
13
+ raise KB::Error.from_faraday(e)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module KB
2
+ module FindOrCreatable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ include Listable
8
+ include Creatable
9
+ end
10
+
11
+ module ClassMethods
12
+ def find_or_create_by(attributes, additional_attributes)
13
+ all(attributes).first || new(create(additional_attributes.merge(attributes)), &:persist!)
14
+ rescue Faraday::Error => e
15
+ raise KB::Error.from_faraday(e)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module KB
2
+ module Findable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def find(key, params = {})
11
+ from_api(kb_client.find(key, params))
12
+ rescue Faraday::ResourceNotFound => e
13
+ raise KB::ResourceNotFound.new(e.response[:status], e.response[:body], e)
14
+ rescue Faraday::Error => e
15
+ raise KB::Error.from_faraday(e)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Inspectionable
2
+ def inspect
3
+ attr_list = attributes.map do |key, value|
4
+ value_str = if value.is_a? ActiveModel::Model
5
+ "#<#{value.class}: #{format '%<id>#018x', id: value.object_id << 1}>"
6
+ else
7
+ value.inspect
8
+ end
9
+ "#{key}: #{value_str}"
10
+ end.join ', '
11
+ "#<#{self.class}: #{format '%<id>#018x', id: object_id << 1} #{attr_list}>"
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module KB
2
+ module Listable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def all(filters = {})
11
+ kb_client.all(filters).map do |pet_parent|
12
+ from_api pet_parent
13
+ end
14
+ rescue Faraday::ConnectionFailed => e
15
+ raise e
16
+ rescue Faraday::Error => e
17
+ raise KB::Error.from_faraday(e)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module KB
2
+ module Queryable
3
+ class KBClientNotSetException < StandardError; end
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_attribute :resolver_factory
8
+ end
9
+
10
+ module ClassMethods
11
+ def kb_client
12
+ if resolver_factory.blank?
13
+ raise KBClientNotSetException, "You probably forgot to call `kb_api ...` on the class #{name}"
14
+ end
15
+
16
+ @kb_client ||= ClientResolver.public_send(resolver_factory)
17
+ end
18
+
19
+ def from_api(attributes)
20
+ new(attributes_from_response(attributes), &:persist!).tap(&:clear_changes_information)
21
+ end
22
+
23
+ private
24
+
25
+ def kb_api(resolver_factory)
26
+ self.resolver_factory = resolver_factory
27
+ end
28
+
29
+ # @abstract Subclass is expected to implement #attributes_from_response
30
+ # @!method attributes_from_response
31
+ # Filter and process the response to return the relevant attributes for entity initialization
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module KB
2
+ module Updatable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def update(key, attributes)
11
+ api_response = kb_client.update(key, attributes)
12
+ attributes_from_response(api_response)
13
+ rescue Faraday::Error => e
14
+ raise KB::Error.from_faraday(e)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module KB
2
+ module Upsertable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Queryable
7
+ end
8
+
9
+ module ClassMethods
10
+ def upsert(attributes)
11
+ from_api kb_client.upsert(attributes)
12
+ rescue Faraday::Error => e
13
+ raise KB::Error.from_faraday(e)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ require 'kb/models/concerns/inspectionable'
2
+
3
+ require 'kb/models/concerns/queryable'
4
+ require 'kb/models/concerns/creatable'
5
+ require 'kb/models/concerns/findable'
6
+ require 'kb/models/concerns/find_or_creatable'
7
+ require 'kb/models/concerns/upsertable'
8
+ require 'kb/models/concerns/updatable'
9
+ require 'kb/models/concerns/listable'
10
+ require 'kb/models/concerns/destroyable'
@@ -0,0 +1,32 @@
1
+ module KB
2
+ class Condition
3
+ include Inspectionable
4
+ include ActiveModel::Model
5
+ include ActiveModel::Attributes
6
+ include ActiveModel::Serializers::JSON
7
+
8
+ FIELDS = %i[key name score usualness urgent information urgency].freeze
9
+
10
+ attribute :key, :string
11
+ attribute :name, :string
12
+ attribute :score, :float
13
+ attribute :usualness, :integer
14
+ attribute :urgency, :string
15
+
16
+ attribute :article, :string, default: ''
17
+ attribute :description_short, :string
18
+ attribute :diagnosis, :string
19
+ attribute :treatment, :string
20
+ attribute :prevention, :string
21
+ attribute :first_aid, :string
22
+ attribute :predisposition_factors, :string
23
+
24
+ alias_attribute :information, :article
25
+
26
+ def urgent
27
+ return false if urgency == 'low'
28
+
29
+ true
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ module KB
2
+ class HubspotRelationship < BaseModel
3
+ include Queryable
4
+
5
+ kb_api :hubspot
6
+
7
+ def self.attributes_from_response(response)
8
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
9
+ end
10
+
11
+ private_class_method :attributes_from_response
12
+
13
+ STRING_FIELDS = %i[kb_key hubspot_id].freeze
14
+ DATE_FIELDS = %i[last_updated_at].freeze
15
+ FIELDS = [*STRING_FIELDS, *DATE_FIELDS].freeze
16
+
17
+ define_attribute_methods(*FIELDS)
18
+
19
+ STRING_FIELDS.each do |field|
20
+ attribute field, :string
21
+ end
22
+
23
+ DATE_FIELDS.each do |field|
24
+ attribute field, :date
25
+ end
26
+
27
+ def self.find(model, model_key)
28
+ response = kb_client.request("#{model}/#{model_key}/relationship")
29
+ new(attributes_from_response(response))
30
+ rescue Faraday::Error => e
31
+ raise KB::Error.from_faraday(e)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,68 @@
1
+ module KB
2
+ class Pet < BaseModel
3
+ include Findable
4
+ include Updatable
5
+ include FindOrCreatable
6
+ include Destroyable
7
+ include Upsertable
8
+
9
+ kb_api :pet
10
+
11
+ def self.attributes_from_response(response)
12
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
13
+ end
14
+
15
+ private_class_method :attributes_from_response
16
+
17
+ STRING_FIELDS = %i[key pet_parent_key name age_category sex breed chip species].freeze
18
+ DATE_FIELDS = %i[birth_date deleted_at].freeze
19
+ BOOLEAN_FIELDS = %i[neutered mongrel].freeze
20
+ FIELDS = [*STRING_FIELDS, *DATE_FIELDS, *BOOLEAN_FIELDS].freeze
21
+
22
+ define_attribute_methods(*FIELDS)
23
+
24
+ STRING_FIELDS.each do |field|
25
+ attribute field, :string
26
+ end
27
+
28
+ BOOLEAN_FIELDS.each do |field|
29
+ attribute field, :boolean
30
+ end
31
+
32
+ DATE_FIELDS.each do |field|
33
+ attribute field, :date
34
+ end
35
+
36
+ def save!
37
+ return unless changed?
38
+
39
+ run_callbacks :save do
40
+ self.attributes = if @persisted
41
+ self.class.update key, changes.transform_values(&:last)
42
+ else
43
+ self.class.create changes.transform_values(&:last)
44
+ end
45
+
46
+ self
47
+ end
48
+ end
49
+
50
+ def destroyed?
51
+ @destroyed
52
+ end
53
+
54
+ def destroy!
55
+ return unless @persisted
56
+
57
+ self.class.destroy key
58
+ @destroyed = true
59
+ freeze
60
+ end
61
+
62
+ def contracts
63
+ self.class.kb_client.request("#{key}/contracts").map do |contract|
64
+ PetContract.from_api(contract)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,77 @@
1
+ module KB
2
+ class PetContract < BaseModel
3
+ include Findable
4
+ include Creatable
5
+ include Updatable
6
+
7
+ kb_api :pet_contract
8
+
9
+ def self.find_by_contract_number(contract_number)
10
+ find("contractnumber/#{contract_number}")
11
+ end
12
+
13
+ def self.attributes_from_response(response)
14
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
15
+ end
16
+
17
+ private_class_method :attributes_from_response
18
+
19
+ STRING_FIELDS = %i[key plan_key product_key pet_key contract_number contract_document status
20
+ source affiliate_online affiliate_offline
21
+ conversion_utm_adgroup conversion_utm_campaign
22
+ conversion_utm_content conversion_utm_medium
23
+ conversion_utm_source conversion_utm_term
24
+ conversion_utm_adgroup_id conversion_utm_campaign_id].freeze
25
+ DATE_FIELDS = %i[policy_start_date policy_expiration_date].freeze
26
+ INTEGER_FIELDS = %i[price_yearly price_monthly price_discount_yearly].freeze
27
+ FIELDS = [*STRING_FIELDS, *DATE_FIELDS, *INTEGER_FIELDS].freeze
28
+
29
+ IMMUTABLE_FIELDS = (FIELDS - %i[status contract_document policy_expiration_date]).freeze
30
+
31
+ define_attribute_methods(*FIELDS)
32
+
33
+ STRING_FIELDS.each do |field|
34
+ attribute field, :string
35
+ end
36
+
37
+ DATE_FIELDS.each do |field|
38
+ attribute field, :date
39
+ end
40
+
41
+ INTEGER_FIELDS.each do |field|
42
+ attribute field, :integer
43
+ end
44
+
45
+ def save!
46
+ return unless changed?
47
+
48
+ run_callbacks :save do
49
+ self.attributes = if @persisted
50
+ self.class.update key, changes.transform_values(&:last)
51
+ else
52
+ self.class.create changes.transform_values(&:last)
53
+ end
54
+
55
+ self
56
+ end
57
+ end
58
+
59
+ def plan
60
+ @plan ||= Plan.all.select { |plan| plan.key == plan_key }
61
+ end
62
+
63
+ def product
64
+ @product ||= Product.find product_key
65
+ end
66
+
67
+ def pet
68
+ @pet ||= Pet.find(pet_key)
69
+ end
70
+
71
+ def hubspot_id
72
+ @hubspot_id ||= KB::HubspotRelationship.find('policies', key).hubspot_id
73
+ rescue KB::ResourceNotFound
74
+ nil
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,111 @@
1
+ module KB
2
+ class PetParent < BaseModel
3
+ include Findable
4
+ include Updatable
5
+ include FindOrCreatable
6
+ include Upsertable
7
+ include Destroyable
8
+
9
+ kb_api :pet_parent
10
+
11
+ def self.all(filters = {})
12
+ filters[:partner_key] = ENV['KB_PARTNER_KEY']
13
+ super(filters)
14
+ end
15
+
16
+ def self.create(attributes = {})
17
+ attributes[:partner_key] = ENV['KB_PARTNER_KEY']
18
+ super(attributes)
19
+ end
20
+
21
+ def self.upsert(attributes)
22
+ attributes[:partner_key] = ENV['KB_PARTNER_KEY']
23
+ super(attributes)
24
+ end
25
+
26
+ def merge!(duplicated_pet_parent_key)
27
+ params = { preservable_pet_parent_key: key,
28
+ erasable_pet_parent_key: duplicated_pet_parent_key }.transform_keys do |key|
29
+ key.to_s.camelize(:lower)
30
+ end
31
+
32
+ response = KB::ClientResolver.admin.request("petparents?#{params.to_query}", method: :put)
33
+ PetParent.from_api response
34
+ rescue Faraday::Error => e
35
+ raise KB::Error.from_faraday(e)
36
+ end
37
+
38
+ def self.attributes_from_response(response)
39
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
40
+ end
41
+
42
+ private_class_method :attributes_from_response
43
+
44
+ STRING_FIELDS = %i[key partner_name first_name last_name prefix_phone_number
45
+ phone_number email country address zip_code nif affiliate_code].freeze
46
+ DATE_FIELDS = %i[birth_date deleted_at].freeze
47
+ BOOLEAN_FIELDS = %i[phone_number_verified email_verified].freeze
48
+ FIELDS = [*STRING_FIELDS, *DATE_FIELDS, *BOOLEAN_FIELDS].freeze
49
+
50
+ define_attribute_methods(*FIELDS)
51
+
52
+ alias phone_number_prefix prefix_phone_number
53
+ alias phone_number_prefix= prefix_phone_number=
54
+
55
+ STRING_FIELDS.each do |field|
56
+ attribute field, :string
57
+ end
58
+
59
+ DATE_FIELDS.each do |field|
60
+ attribute field, :date
61
+ end
62
+
63
+ BOOLEAN_FIELDS.each do |field|
64
+ attribute field, :boolean
65
+ end
66
+
67
+ attribute :first_name, :string, default: ''
68
+
69
+ def save!
70
+ return unless changed?
71
+
72
+ run_callbacks :save do
73
+ self.attributes = if @persisted
74
+ self.class.update key, changes.transform_values(&:last)
75
+ else
76
+ self.class.create changes.transform_values(&:last)
77
+ end
78
+
79
+ self
80
+ end
81
+ end
82
+
83
+ def destroyed?
84
+ @destroyed
85
+ end
86
+
87
+ def destroy!
88
+ return unless @persisted
89
+
90
+ self.class.destroy key
91
+ @destroyed = true
92
+ freeze
93
+ end
94
+
95
+ def full_phone_number
96
+ "#{phone_number_prefix}#{phone_number}"
97
+ end
98
+
99
+ def pets
100
+ self.class.kb_client.request("#{key}/pets").map do |pet|
101
+ Pet.from_api(pet)
102
+ end
103
+ end
104
+
105
+ def contracts
106
+ self.class.kb_client.request("#{key}/contracts").map do |contract|
107
+ PetContract.from_api(contract)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,44 @@
1
+ module KB
2
+ class Plan < BaseModel
3
+ include Listable
4
+
5
+ kb_api :plan
6
+
7
+ def self.attributes_from_response(response)
8
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
9
+ end
10
+
11
+ private_class_method :attributes_from_response
12
+
13
+ STRING_FIELDS = %i[key description plan_name type].freeze
14
+ HASH_FIELDS = %i[benefits price].freeze
15
+ FIELDS = [*STRING_FIELDS, *HASH_FIELDS, :plan_life_in_months, :buyable].freeze
16
+
17
+ define_attribute_methods(*FIELDS)
18
+
19
+ attribute :plan_life_in_months, :integer
20
+ attribute :buyable, :boolean
21
+
22
+ STRING_FIELDS.each do |field|
23
+ attribute field, :string
24
+ end
25
+
26
+ HASH_FIELDS.each do |field|
27
+ attribute field
28
+ end
29
+
30
+ def save!
31
+ return unless changed?
32
+
33
+ run_callbacks :save do
34
+ self.attributes = if @persisted
35
+ self.class.update key, changes.transform_values(&:last)
36
+ else
37
+ self.class.create changes.transform_values(&:last)
38
+ end
39
+
40
+ self
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module KB
2
+ class Product < BaseModel
3
+ include Listable
4
+ include Findable
5
+
6
+ kb_api :product
7
+
8
+ def self.by_country(country)
9
+ all(country: country)
10
+ end
11
+
12
+ def self.attributes_from_response(response)
13
+ response.transform_keys(&:underscore).transform_keys(&:to_sym).slice(*FIELDS)
14
+ end
15
+
16
+ private_class_method :attributes_from_response
17
+
18
+ STRING_FIELDS = %i[key country name type].freeze
19
+ STRING_ARRAY_FIELDS = %i[exclusions inclusions features claimable_by languages].freeze
20
+ FIELDS = [*STRING_FIELDS, *STRING_ARRAY_FIELDS, :purchasable].freeze
21
+
22
+ define_attribute_methods(*FIELDS)
23
+
24
+ attribute :purchasable, :boolean
25
+
26
+ STRING_FIELDS.each do |field|
27
+ attribute field, :string
28
+ end
29
+
30
+ STRING_ARRAY_FIELDS.each do |field|
31
+ attribute field, :array_of_strings
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ module KB
2
+ class Symptom
3
+ include Inspectionable
4
+ include ActiveModel::Model
5
+ include ActiveModel::Attributes
6
+ include ActiveModel::Serializers::JSON
7
+
8
+ attribute :key, :string
9
+ attribute :name, :string
10
+ attribute :presence, :string
11
+ attribute :duration, :string
12
+ attribute :frequency, :string
13
+
14
+ attribute :urgency, :string
15
+ attribute :article, :string, default: ''
16
+
17
+ alias_attribute :information, :article
18
+
19
+ def urgent
20
+ return false if urgency == 'low'
21
+
22
+ true
23
+ end
24
+ end
25
+ end
data/lib/kb/models.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'kb/models/concerns'
2
+ require 'kb/models/base_model'
3
+
4
+ require 'kb/models/condition'
5
+ require 'kb/models/symptom'
6
+ require 'kb/models/assessment'
7
+
8
+ require 'kb/models/pet_contract'
9
+ require 'kb/models/pet_parent'
10
+ require 'kb/models/pet'
11
+ require 'kb/models/product'
12
+ require 'kb/models/plan'
13
+ require 'kb/models/breed'
14
+
15
+ require 'kb/models/hubspot_relationship'
@@ -0,0 +1,13 @@
1
+ module Type
2
+ class ArrayOfConditionsType < ActiveModel::Type::Value
3
+ CONDITION_KEYS = KB::Condition.attribute_types.keys.map(&:to_sym)
4
+
5
+ def cast(value)
6
+ (value || []).map do |v|
7
+ next v if v.is_a? KB::Condition
8
+
9
+ KB::Condition.new v.symbolize_keys.slice(*CONDITION_KEYS)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Type
2
+ class ArrayOfStringsType < ActiveModel::Type::Value
3
+ def cast(values)
4
+ return [] if values.blank?
5
+
6
+ values.map(&:to_s)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Type
2
+ class ArrayOfSymptomsType < ActiveModel::Type::Value
3
+ SYMPTOM_KEYS = KB::Symptom.attribute_types.keys.map(&:to_sym)
4
+
5
+ def cast(value)
6
+ (value || []).map do |v|
7
+ next v if v.is_a? KB::Symptom
8
+
9
+ KB::Symptom.new v.symbolize_keys.slice(*SYMPTOM_KEYS)
10
+ end
11
+ end
12
+ end
13
+ end