capsule_crm 1.2.0 → 1.3.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/capsule_crm/address.rb +4 -3
  4. data/lib/capsule_crm/associations/belongs_to.rb +2 -1
  5. data/lib/capsule_crm/associations/belongs_to_association.rb +19 -2
  6. data/lib/capsule_crm/associations/belongs_to_finder.rb +46 -0
  7. data/lib/capsule_crm/associations/has_many_association.rb +23 -9
  8. data/lib/capsule_crm/associations/has_many_proxy.rb +38 -4
  9. data/lib/capsule_crm/case.rb +33 -236
  10. data/lib/capsule_crm/configuration.rb +1 -1
  11. data/lib/capsule_crm/connection.rb +3 -0
  12. data/lib/capsule_crm/contactable.rb +1 -1
  13. data/lib/capsule_crm/country.rb +7 -13
  14. data/lib/capsule_crm/currency.rb +7 -13
  15. data/lib/capsule_crm/custom_field.rb +14 -54
  16. data/lib/capsule_crm/custom_field_definition.rb +36 -0
  17. data/lib/capsule_crm/email.rb +4 -3
  18. data/lib/capsule_crm/gettable.rb +11 -0
  19. data/lib/capsule_crm/hash_helper.rb +5 -0
  20. data/lib/capsule_crm/history.rb +37 -252
  21. data/lib/capsule_crm/milestone.rb +9 -9
  22. data/lib/capsule_crm/normalizer.rb +85 -0
  23. data/lib/capsule_crm/opportunity.rb +30 -271
  24. data/lib/capsule_crm/organization.rb +19 -197
  25. data/lib/capsule_crm/party.rb +13 -26
  26. data/lib/capsule_crm/persistence/configuration.rb +25 -0
  27. data/lib/capsule_crm/persistence/deletable.rb +14 -0
  28. data/lib/capsule_crm/persistence/persistable.rb +76 -0
  29. data/lib/capsule_crm/persistence.rb +3 -0
  30. data/lib/capsule_crm/person.rb +19 -194
  31. data/lib/capsule_crm/phone.rb +4 -3
  32. data/lib/capsule_crm/querying/configuration.rb +21 -0
  33. data/lib/capsule_crm/querying/find_all.rb +16 -0
  34. data/lib/capsule_crm/querying/find_one.rb +14 -0
  35. data/lib/capsule_crm/querying/findable.rb +14 -0
  36. data/lib/capsule_crm/querying.rb +4 -0
  37. data/lib/capsule_crm/serializable.rb +38 -0
  38. data/lib/capsule_crm/serializer.rb +54 -7
  39. data/lib/capsule_crm/task.rb +16 -96
  40. data/lib/capsule_crm/track.rb +5 -10
  41. data/lib/capsule_crm/user.rb +3 -15
  42. data/lib/capsule_crm/version.rb +1 -1
  43. data/lib/capsule_crm/website.rb +4 -2
  44. data/lib/capsule_crm.rb +15 -5
  45. data/spec/fabricators/case_fabricator.rb +1 -0
  46. data/spec/fabricators/history_fabricator.rb +1 -0
  47. data/spec/fabricators/opportunity_fabricator.rb +1 -0
  48. data/spec/lib/capsule_crm/associations/belongs_to_finder_spec.rb +48 -0
  49. data/spec/lib/capsule_crm/associations/belongs_to_spec.rb +34 -0
  50. data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +54 -14
  51. data/spec/lib/capsule_crm/associations/has_many_spec.rb +15 -2
  52. data/spec/lib/capsule_crm/case_spec.rb +20 -330
  53. data/spec/lib/capsule_crm/country_spec.rb +1 -16
  54. data/spec/lib/capsule_crm/currency_spec.rb +1 -18
  55. data/spec/lib/capsule_crm/custom_field_definition_spec.rb +59 -0
  56. data/spec/lib/capsule_crm/custom_field_spec.rb +2 -27
  57. data/spec/lib/capsule_crm/history_spec.rb +14 -389
  58. data/spec/lib/capsule_crm/milestone_spec.rb +1 -23
  59. data/spec/lib/capsule_crm/normalizer_spec.rb +11 -0
  60. data/spec/lib/capsule_crm/opportunity_spec.rb +22 -341
  61. data/spec/lib/capsule_crm/organization_spec.rb +39 -60
  62. data/spec/lib/capsule_crm/party_spec.rb +37 -59
  63. data/spec/lib/capsule_crm/person_spec.rb +49 -247
  64. data/spec/lib/capsule_crm/serializer_spec.rb +25 -4
  65. data/spec/lib/capsule_crm/task_spec.rb +21 -250
  66. data/spec/lib/capsule_crm/track_spec.rb +1 -15
  67. data/spec/lib/capsule_crm/user_spec.rb +1 -14
  68. data/spec/support/{countries.json → all_countries.json} +0 -0
  69. data/spec/support/{currencies.json → all_currencies.json} +0 -0
  70. data/spec/support/{milestones.json → all_milestones.json} +0 -0
  71. data/spec/support/{tracks.json → all_tracks.json} +0 -0
  72. data/spec/support/custom_field_definitions.json +19 -0
  73. data/spec/support/helpers.rb +3 -2
  74. data/spec/support/no_cases.json +5 -0
  75. data/spec/support/no_countries.json +5 -0
  76. data/spec/support/no_currencies.json +5 -0
  77. data/spec/support/no_milestones.json +5 -0
  78. data/spec/support/no_opportunities.json +5 -0
  79. data/spec/support/no_tasks.json +5 -0
  80. data/spec/support/no_tracks.json +5 -0
  81. data/spec/support/no_users.json +5 -0
  82. data/spec/support/shared_examples/deletable.rb +15 -0
  83. data/spec/support/shared_examples/find_all.rb +34 -0
  84. data/spec/support/shared_examples/find_one.rb +23 -0
  85. data/spec/support/shared_examples/persistable.rb +318 -0
  86. data/spec/support/single_person.json +16 -0
  87. metadata +60 -15
  88. data/lib/capsule_crm/attributes.rb +0 -11
  89. data/lib/capsule_crm/capsule_jsonable.rb +0 -13
  90. data/lib/capsule_crm/collection.rb +0 -9
  91. data/spec/support/single_user.json +0 -25
@@ -7,8 +7,17 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
- include CapsuleCRM::Attributes
11
- include CapsuleCRM::Collection
10
+ include CapsuleCRM::Querying::Configuration
11
+ include CapsuleCRM::Serializable
12
+
13
+ serializable_config do |config|
14
+ config.root = 'customField'
15
+ config.collection_root = 'customFields'
16
+ end
17
+
18
+ queryable_config do |config|
19
+ config.plural = 'customfields'
20
+ end
12
21
 
13
22
  attribute :id, Integer
14
23
  attribute :label, String
@@ -20,62 +29,13 @@ module CapsuleCRM
20
29
  validates :id, numericality: { allow_blank: true }
21
30
  validates :label, presence: true
22
31
 
23
- belongs_to :party, class_name: 'CapsuleCRM::Party'
24
-
25
- def self._for_party(party_id)
26
- init_collection(
27
- CapsuleCRM::Connection.
28
- get("/api/party/#{party_id}/customfields")['customFields'].
29
- fetch('customField', nil)
30
- )
31
- end
32
+ belongs_to :party
33
+ belongs_to :opportunity
34
+ belongs_to :case
32
35
 
33
36
  class << self
34
37
  alias :_for_organization :_for_party
35
38
  alias :_for_person :_for_party
36
39
  end
37
-
38
- def self.create(attributes = {})
39
- new(attributes).tap(&:save)
40
- end
41
-
42
- def self.create!(attribute = {})
43
- new(attributes).tap(&:save)
44
- end
45
-
46
- def save
47
- if valid?
48
- update_record
49
- else
50
- false
51
- end
52
- end
53
-
54
- def save!
55
- if valid?
56
- update_record
57
- else
58
- raise CapsuleCRM::Errors::RecordInvalid.new(self)
59
- end
60
- end
61
-
62
- def destroy
63
- end
64
-
65
- def to_capsule_json
66
- { 'customFields' => serializer.serialize }
67
- end
68
-
69
- private
70
-
71
- def serializer
72
- @serializer ||= CapsuleCRM::Serializer.new(self, root: 'customField')
73
- end
74
-
75
- def update_record
76
- CapsuleCRM::Connection.post(
77
- "/api/party/#{party.id}/customfields", to_capsule_json
78
- )
79
- end
80
40
  end
81
41
  end
@@ -0,0 +1,36 @@
1
+ module CapsuleCRM
2
+ class CustomFieldDefinition
3
+ include Virtus
4
+ include CapsuleCRM::Serializable
5
+ include CapsuleCRM::Gettable
6
+
7
+ serializable_config do |config|
8
+ config.collection_root = :customFieldDefinitions
9
+ config.root = :customFieldDefinition
10
+ end
11
+
12
+ attribute :id, Integer
13
+ attribute :tag, String
14
+ attribute :label, String
15
+ attribute :type, String
16
+ attribute :options, String
17
+
18
+ def self.for_parties
19
+ normalizer.normalize_collection get('/api/party/customfield/definitions')
20
+ end
21
+
22
+ def self.for_opportunities
23
+ normalizer.normalize_collection(
24
+ get('/api/opportunity/customfield/definitions')
25
+ )
26
+ end
27
+
28
+ def self.for_cases
29
+ normalizer.normalize_collection get('/api/kase/customfield/definitions')
30
+ end
31
+
32
+ def self.normalizer
33
+ @normalizer ||= CapsuleCRM::Normalizer.new(self)
34
+ end
35
+ end
36
+ end
@@ -1,11 +1,12 @@
1
1
  module CapsuleCRM
2
2
  class Email
3
3
  include Virtus
4
-
4
+ include CapsuleCRM::Serializable
5
5
  extend ActiveModel::Naming
6
- include ActiveModel::Serializers::JSON
7
6
 
8
- include CapsuleCRM::CapsuleJsonable
7
+ serializable_config do |config|
8
+ config.include_root = false
9
+ end
9
10
 
10
11
  attribute :type
11
12
  attribute :email_address
@@ -0,0 +1,11 @@
1
+ module CapsuleCRM
2
+ module Gettable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def get(path)
7
+ CapsuleCRM::Connection.get(path)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -8,6 +8,11 @@ module CapsuleCRM
8
8
  end
9
9
  end
10
10
 
11
+ def self.underscore_keys(hash)
12
+ underscore_keys!(hash)
13
+ hash
14
+ end
15
+
11
16
  def self.camelize_keys!(hash)
12
17
  hash.keys.each do |key|
13
18
  hash[key.to_s.camelize(:lower)] = hash.delete(key)
@@ -7,8 +7,26 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
- include CapsuleCRM::Attributes
11
- include CapsuleCRM::Collection
10
+ include CapsuleCRM::Persistence::Persistable
11
+ include CapsuleCRM::Persistence::Deletable
12
+ include CapsuleCRM::Querying::Configuration
13
+ include CapsuleCRM::Querying::FindOne
14
+ include CapsuleCRM::Serializable
15
+
16
+ persistable_config do |config|
17
+ config.create = lambda do |history|
18
+ "#{history.belongs_to_api_name}/#{history.belongs_to_id}/history"
19
+ end
20
+ end
21
+
22
+ serializable_config do |config|
23
+ config.root = :historyItem
24
+ config.collection_root = :history
25
+ end
26
+
27
+ queryable_config do |config|
28
+ config.plural = :history
29
+ end
12
30
 
13
31
  attribute :id, Integer
14
32
  attribute :type, String
@@ -16,63 +34,25 @@ module CapsuleCRM
16
34
  attribute :subject, String
17
35
  attribute :note, String
18
36
 
19
- has_many :attachments, class_name: 'CapsuleCRM::Attachment'
20
- has_many :participants, class_name: 'CapsuleCRM::Participant'
37
+ has_many :attachments
38
+ has_many :participants
21
39
 
22
- belongs_to :creator, class_name: 'CapsuleCRM::Person',
23
- serializable_key: :creator
24
- belongs_to :party, class_name: 'CapsuleCRM::Party', serialize: false
25
- belongs_to :kase, class_name: 'CapsuleCRM::Case',
26
- foreign_key: :case_id, serialize: false
27
- belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity',
28
- serialize: false
40
+ belongs_to :creator, serializable_key: :creator,
41
+ class_name: 'CapsuleCRM::Person'
42
+ belongs_to :party, serialize: false
43
+ belongs_to :case, serialize: false
44
+ belongs_to :opportunity, serialize: false
29
45
 
30
46
  validates :id, numericality: { allow_blank: true }
31
47
  validates :note, presence: true
32
- validates :party, :kase, :opportunity,
48
+ validates :party, :case, :opportunity,
33
49
  presence: { if: :belongs_to_required? }
34
50
 
35
- def self._for_party(party_id)
36
- init_collection(
37
- CapsuleCRM::Connection.
38
- get("/api/party/#{party_id}/history")['history'].
39
- fetch('historyItem', nil)
40
- )
41
- end
42
-
43
51
  class << self
44
52
  alias :_for_organization :_for_party
45
53
  alias :_for_person :_for_party
46
54
  end
47
55
 
48
- def self._for_case(case_id)
49
- init_collection(
50
- CapsuleCRM::Connection.
51
- get("/api/kase/#{case_id}/history")['history']['historyItem']
52
- )
53
- end
54
-
55
- def self._for_opportunity(opportunity_id)
56
- init_collection(
57
- CapsuleCRM::Connection.
58
- get("/api/opportunity/#{opportunity_id}/history")\
59
- ['history']['historyItem']
60
- )
61
- end
62
-
63
- # Public: find a CapsuleCRM::History by ID
64
- #
65
- # id - The Integer CapsuleCRM::History ID
66
- #
67
- # Examples
68
- #
69
- # CapsuleCRM::History.find(2)
70
- #
71
- # Returns a CapsuleCRM::History object
72
- def self.find(id)
73
- new CapsuleCRM::Connection.get("/api/history/#{id}")['historyItem']
74
- end
75
-
76
56
  # Public: Set the creator of this history item
77
57
  #
78
58
  # user - The String username OR a CapsuleCRM::User object
@@ -94,220 +74,25 @@ module CapsuleCRM
94
74
  self
95
75
  end
96
76
 
97
- # Public: create a CapsuleCRM::History item and persist it
98
- #
99
- # attributes - The Hash of attributes (default: {}):
100
- # :note - The String note
101
- # :creator - The CapsuleCRM::User who created this history
102
- # item
103
- # :entry_date - The date when this history item was created
104
- #
105
- # Examples
106
- #
107
- # CapsuleCRM::History.create(note: 'Some history note text')
108
- #
109
- # person = CapsuleCRM::User.find_by_username('some.username')
110
- # CapsuleCRM::History.create(
111
- # note: 'another note to add to the history', person: person,
112
- # entry_date: Time.now
113
- # )
114
- #
115
- # Returns a CapsuleCRM::History object
116
- def self.create(attributes = {})
117
- new(attributes).tap(&:save)
118
- end
119
-
120
- # Public: create a CapsuleCRM::History item and persist it. If persistence
121
- # is not possible then raise an error
122
- #
123
- # attributes - The Hash of attributes (default: {}):
124
- # :note - The String note
125
- # :creator - The CapsuleCRM::User who created this history
126
- # item
127
- # :entry_date - The date when this history item was created
128
- #
129
- # Examples
130
- #
131
- # CapsuleCRM::History.create!(note: 'Some history note text')
132
- #
133
- # person = CapsuleCRM::User.find_by_username('some.username')
134
- # CapsuleCRM::History.create!(
135
- # note: 'another note to add to the history', person: person,
136
- # entry_date: Time.now
137
- # )
138
- #
139
- # CapsuleCRM::History.create! {}
140
- # => CapsuleCRM::Errors::RecordInvalid
141
- #
142
- # Returns a CapsuleCRM::History object
143
- def self.create!(attributes = {})
144
- new(attributes).tap(&:save!)
145
- end
146
-
147
- # Public: update the attributes of a CapsuleCRM::History item and persist
148
- # the changes
149
- #
150
- # attributes - The Hash of attributes (default: {}):
151
- # :note - The String note
152
- # :creator - The String creator username OR
153
- # a CapsuleCRM::Person object
154
- # :entry_date - The DateTime when the history item was
155
- # created
156
- #
157
- # Examples
158
- #
159
- # history = CapsuleCRM::History.find(1)
160
- # history.update_attributes note: 'some updated note text'
161
- #
162
- # Returns a CapsuleCRM::History item or false
163
- def update_attributes(attributes = {})
164
- self.attributes = attributes
165
- save
166
- end
167
-
168
- # Public: update the attributes of a CapsuleCRM::History item and persist
169
- # the changes. If persistence is not possible then raise an error
170
- #
171
- # attributes - The Hash of attributes (default: {}):
172
- # :note - The String note
173
- # :creator - The String creator username OR
174
- # a CapsuleCRM::Person object
175
- # :entry_date - The DateTime when the history item was
176
- # created
177
- #
178
- # Examples
179
- #
180
- # history = CapsuleCRM::History.find(1)
181
- # history.update_attributes note: 'some updated note text'
182
- #
183
- # history.update_attributes note: nil
184
- # => CapsuleCRM::Errors::RecordInvalid
185
- #
186
- # Returns a CapsuleCRM::History item or a CapsuleCRM::Errors::RecordInvalid
187
- def update_attributes!(attributes = {})
188
- self.attributes = attributes
189
- save!
190
- end
191
-
192
- # Public: Save this history item. If it is already existing in capsule crm
193
- # then update it, otherwise create a new one
194
- #
195
- # Examples
196
- #
197
- # CapsuleCRM::History.new(note: 'some note text').save
198
- #
199
- # Returns a CapsuleCRM::History object of false
200
- def save
201
- if valid?
202
- new_record? ? create_record : update_record
203
- else
204
- false
205
- end
206
- end
207
-
208
- # Public: Save this history item. If it is already existing in capsule crm
209
- # then update it, otherwise create a new one. If persistence is not possible
210
- # then raise an error
211
- #
212
- # Examples
213
- #
214
- # CapsuleCRM::History.new(note: 'the note text').save!
215
- #
216
- # CapsuleCRM::History.new.save!
217
- # => CapsuleCRM::Errors::RecordInvalid
218
- #
219
- # Returns a CapsuleCRM::History object
220
- def save!
221
- if valid?
222
- new_record? ? create_record : update_record
223
- else
224
- raise CapsuleCRM::Errors::RecordInvalid.new(self)
225
- end
226
- end
227
-
228
- # Public: Delete this history item from capsule crm.
229
- #
230
- # Examples
231
- #
232
- # CapsuleCRM::History.find(1).destroy
233
- #
234
- # Returns the CapsuleCRM::History object
235
- def destroy
236
- self.id = nil if CapsuleCRM::Connection.delete("/api/history/#{id}")
237
- self
238
- end
239
-
240
- # Public: Is this history item a new record?
241
- #
242
- # Examples
243
- #
244
- # CapsuleCRM::History.new.new_record?
245
- # => true
246
- #
247
- # CapsuleCRM::History.find(1).new_record?
248
- # => false
249
- def new_record?
250
- !id
251
- end
252
-
253
- # Public: Is this history item persisted?
254
- #
255
- # Examples
256
- #
257
- # CapsuleCRM::History.new.persisted?
258
- # => fale
259
- #
260
- # CapsuleCRM::History.find(1).persisted?
261
- # => true
262
- def persisted?
263
- !new_record?
264
- end
265
-
266
- # Public: Generate the attributes hash to send to capsule
267
- #
268
- # Examples
269
- #
270
- # CapsuleCRM::History.find(1).to_capsule_json
271
- #
272
- # Returns a Hash of attributes
273
- def to_capsule_json
274
- serializer.serialize
275
- end
276
-
277
- private
278
-
279
- def serializer
280
- @serializer ||= CapsuleCRM::Serializer.new(self, root: :historyItem)
281
- end
282
-
283
- def belongs_to_required?
284
- party.blank? && kase.blank? && opportunity.blank?
285
- end
286
-
287
- def create_record
288
- self.attributes = CapsuleCRM::Connection.post(
289
- "/api/#{belongs_to_api_name}/#{belongs_to_id}/history", to_capsule_json
290
- )
291
- self
292
- end
293
-
294
77
  def belongs_to_api_name
295
78
  {
296
- person: 'party', organization: 'party', case: 'kase',
79
+ person: 'party', organization: 'party', case: 'case',
297
80
  opportunity: 'opportunity'
298
81
  }.stringify_keys[belongs_to_name]
299
82
  end
300
83
 
301
- def belongs_to_name
302
- (party || kase || opportunity).class.to_s.demodulize.downcase
84
+ def belongs_to_id
85
+ (party || self.case || opportunity).try(:id)
303
86
  end
304
87
 
305
- def belongs_to_id
306
- (party || kase || opportunity).id
88
+ private
89
+
90
+ def belongs_to_required?
91
+ party.blank? && self.case.blank? && opportunity.blank?
307
92
  end
308
93
 
309
- def update_record
310
- CapsuleCRM::Connection.put("/api/history/#{id}", to_capsule_json)
94
+ def belongs_to_name
95
+ (party || self.case || opportunity).class.to_s.demodulize.downcase
311
96
  end
312
97
  end
313
98
  end
@@ -1,8 +1,15 @@
1
1
  module CapsuleCRM
2
2
  class Milestone
3
- include Virtus
4
- include CapsuleCRM::Collection
5
3
  include ActiveModel::Validations
4
+ include Virtus
5
+
6
+ include CapsuleCRM::Querying::Configuration
7
+ include CapsuleCRM::Querying::FindAll
8
+ include CapsuleCRM::Serializable
9
+
10
+ queryable_config do |config|
11
+ config.plural = 'opportunity/milestones'
12
+ end
6
13
 
7
14
  attribute :id, Integer
8
15
  attribute :name, String
@@ -12,13 +19,6 @@ module CapsuleCRM
12
19
 
13
20
  validates :id, numericality: { allow_blank: true }
14
21
 
15
- def self.all
16
- init_collection(
17
- CapsuleCRM::Connection.
18
- get('/api/opportunity/milestones')['milestones']['milestone']
19
- )
20
- end
21
-
22
22
  def self.find(id)
23
23
  all.select { |item| item.id == id }.first
24
24
  end
@@ -0,0 +1,85 @@
1
+ module CapsuleCRM
2
+ class Normalizer
3
+ attr_reader :klass, :options
4
+
5
+ def initialize(klass, options = {})
6
+ @klass = klass
7
+ @options = options
8
+ end
9
+
10
+ def normalize(attrs = {})
11
+ subclasses? ? normalize_subclass(attrs) : normalize_single(attrs)
12
+ end
13
+
14
+ def normalize_collection(attrs)
15
+ if subclasses?
16
+ normalize_subclass_collection(attrs)
17
+ else
18
+ normalize_standard_collection(attrs)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def root
25
+ @root ||= options[:root] || klass.serializable_options.root
26
+ end
27
+
28
+ def collection_root
29
+ @collection_root ||= options[:collection_root] ||
30
+ klass.serializable_options.collection_root
31
+ end
32
+
33
+ def attribute_to_assign
34
+ @attribute_to_assign ||= klass.serializable_options.attribute_to_assign
35
+ end
36
+
37
+ def normalize_subclass(attrs)
38
+ hash_helper.underscore_keys!(attrs[attrs.keys.first])
39
+ klass.child_classes[attrs.keys.first].constantize.new(
40
+ attrs[attrs.keys.first]
41
+ )
42
+ end
43
+
44
+ def normalize_single(attrs)
45
+ hash_helper.underscore_keys!(attrs[root.to_s])
46
+ klass.new(attrs[root.to_s])
47
+ end
48
+
49
+ def normalize_subclass_collection(attrs)
50
+ [].tap do |objects|
51
+ attrs[collection_root.to_s].each do |key, value|
52
+ next unless klass.child_classes.keys.include?(key)
53
+ if value.is_a?(Hash)
54
+ objects << klass.child_classes[key].constantize.
55
+ new(hash_helper.underscore_keys(value))
56
+ else
57
+ value.each do |attributes|
58
+ objects << klass.child_classes[key].constantize.
59
+ new(hash_helper.underscore_keys(attributes))
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def normalize_standard_collection(attrs)
67
+ return [] unless attrs[collection_root.to_s][root.to_s]
68
+ [attrs[collection_root.to_s][root.to_s]].flatten.map do |singular|
69
+ if attribute_to_assign
70
+ klass.new attribute_to_assign => singular
71
+ else
72
+ klass.new hash_helper.underscore_keys(singular)
73
+ end
74
+ end
75
+ end
76
+
77
+ def subclasses?
78
+ root.is_a?(Array)
79
+ end
80
+
81
+ def hash_helper
82
+ @hash_helper ||= CapsuleCRM::HashHelper
83
+ end
84
+ end
85
+ end