cfoundry 1.4.0 → 1.5.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.
@@ -1,4 +1,10 @@
1
1
  require "cfoundry/validator"
2
+ require "cfoundry/v2/model_magic/client_extensions"
3
+ require "cfoundry/v2/model_magic/has_summary"
4
+ require "cfoundry/v2/model_magic/attribute"
5
+ require "cfoundry/v2/model_magic/to_one"
6
+ require "cfoundry/v2/model_magic/to_many"
7
+ require "cfoundry/v2/model_magic/queryable_by"
2
8
 
3
9
  module CFoundry::V2
4
10
  # object name -> module containing query methods
@@ -15,6 +21,13 @@ module CFoundry::V2
15
21
  end
16
22
 
17
23
  module ModelMagic
24
+ include ModelMagic::ClientExtensions
25
+ include ModelMagic::HasSummary
26
+ include ModelMagic::Attribute
27
+ include ModelMagic::ToOne
28
+ include ModelMagic::ToMany
29
+ include ModelMagic::QueryableBy
30
+
18
31
  attr_reader :scoped_organization, :scoped_space
19
32
 
20
33
  def object_name
@@ -28,14 +41,6 @@ module CFoundry::V2
28
41
  :"#{object_name}s"
29
42
  end
30
43
 
31
- def define_client_methods(&blk)
32
- ClientMethods.module_eval(&blk)
33
- end
34
-
35
- def define_base_client_methods(&blk)
36
- BaseClientMethods.module_eval(&blk)
37
- end
38
-
39
44
  def defaults
40
45
  @defaults ||= {}
41
46
  end
@@ -53,132 +58,10 @@ module CFoundry::V2
53
58
  end
54
59
 
55
60
  def inherited(klass)
56
- singular = klass.object_name
57
- plural = klass.plural_object_name
58
-
59
- define_base_client_methods do
60
- define_method(singular) do |guid, *args|
61
- get("v2", plural, guid,
62
- :accept => :json,
63
- :params => ModelMagic.params_from(args)
64
- )
65
- end
66
-
67
- define_method(plural) do |*args|
68
- all_pages(
69
- get("v2", plural,
70
- :accept => :json,
71
- :params => ModelMagic.params_from(args)
72
- )
73
- )
74
- end
75
- end
76
-
77
- define_client_methods do
78
- define_method(singular) do |*args|
79
- guid, partial, _ = args
80
-
81
- x = klass.new(guid, self, nil, partial)
82
-
83
- # when creating an object, automatically set the org/space
84
- unless guid
85
- if klass.scoped_organization && current_organization
86
- x.send(:"#{klass.scoped_organization}=", current_organization)
87
- end
88
-
89
- if klass.scoped_space && current_space
90
- x.send(:"#{klass.scoped_space}=", current_space)
91
- end
92
- end
93
-
94
- x
95
- end
96
-
97
- define_method(plural) do |*args|
98
- # use current org/space
99
- if klass.scoped_space && current_space
100
- current_space.send(plural, *args)
101
- elsif klass.scoped_organization && current_organization
102
- current_organization.send(plural, *args)
103
- else
104
- @base.send(plural, *args).collect do |json|
105
- send(:"make_#{singular}", json)
106
- end
107
- end
108
- end
109
-
110
- define_method(:"#{singular}_from") do |path, *args|
111
- send(
112
- :"make_#{singular}",
113
- @base.get(
114
- path,
115
- :accept => :json,
116
- :params => ModelMagic.params_from(args)))
117
- end
118
-
119
- define_method(:"#{plural}_from") do |path, *args|
120
- objs = @base.all_pages(
121
- @base.get(
122
- path,
123
- :accept => :json,
124
- :params => ModelMagic.params_from(args)))
125
-
126
- objs.collect do |json|
127
- send(:"make_#{singular}", json)
128
- end
129
- end
130
-
131
- define_method(:"make_#{singular}") do |json|
132
- klass.new(
133
- json[:metadata][:guid],
134
- self,
135
- json)
136
- end
137
- end
138
-
61
+ add_client_methods(klass)
139
62
  has_summary
140
63
  end
141
64
 
142
- def attribute(name, type, opts = {})
143
- attributes[name] = opts
144
- json_name = opts[:at] || name
145
-
146
- default = opts[:default]
147
-
148
- if has_default = opts.key?(:default)
149
- defaults[name] = default
150
- end
151
-
152
- define_method(name) do
153
- return @cache[name] if @cache.key?(name)
154
- return nil unless persisted?
155
-
156
- @cache[name] =
157
- if manifest[:entity].key?(json_name)
158
- manifest[:entity][json_name]
159
- else
160
- default
161
- end
162
- end
163
-
164
- define_method(:"#{name}=") do |val|
165
- unless has_default && val == default
166
- CFoundry::Validator.validate_type(val, type)
167
- end
168
-
169
- @cache[name] = val
170
-
171
- @manifest ||= {}
172
- @manifest[:entity] ||= {}
173
-
174
- old = @manifest[:entity][json_name]
175
- @changes[name] = [old, val] if old != val
176
- @manifest[:entity][json_name] = val
177
-
178
- @diff[json_name] = val
179
- end
180
- end
181
-
182
65
  def scoped_to_organization(relation = :organization)
183
66
  @scoped_organization = relation
184
67
  end
@@ -187,248 +70,6 @@ module CFoundry::V2
187
70
  @scoped_space = relation
188
71
  end
189
72
 
190
- def to_one(name, opts = {})
191
- to_one_relations[name] = opts
192
-
193
- association_name = opts[:as] || name
194
- default = opts[:default]
195
-
196
- if has_default = opts.key?(:default)
197
- defaults[:"#{name}_guid"] = default
198
- end
199
-
200
- define_method(name) do
201
- return @cache[name] if @cache.key?(name)
202
- return @client.send(name) unless persisted?
203
-
204
- @cache[name] =
205
- if @manifest && @manifest[:entity].key?(name)
206
- @client.send(:"make_#{association_name}", @manifest[:entity][name])
207
- elsif url = send("#{name}_url")
208
- @client.send(:"#{association_name}_from", url)
209
- else
210
- default
211
- end
212
- end
213
-
214
- define_method("create_#{name}") do |*args|
215
- associated_instance = @client.send(:"#{association_name}")
216
- args.first.each do |name, value|
217
- associated_instance.send("#{name}=", value)
218
- end if args.first.is_a? Hash
219
-
220
- associated_instance.create!
221
- self.send("#{name}=", associated_instance)
222
- end
223
-
224
- define_method(:"#{name}_url") do
225
- manifest[:entity][:"#{name}_url"]
226
- end
227
-
228
- define_method(:"#{name}=") do |assigned_value|
229
- klass = self.class.objects[association_name]
230
-
231
- unless has_default && assigned_value == default
232
- CFoundry::Validator.validate_type(assigned_value, klass)
233
- end
234
-
235
- @manifest ||= {}
236
- @manifest[:entity] ||= {}
237
-
238
- old_guid = @manifest[:entity][:"#{name}_guid"]
239
- association_guid = assigned_value ? assigned_value.guid : nil
240
-
241
- if old_guid != (association_guid)
242
- old_obj =
243
- @cache[name] || klass.new(@client, old_guid, @manifest[:entity][name])
244
-
245
- @changes[name] = [old_obj, assigned_value]
246
- end
247
-
248
- @cache[name] = assigned_value
249
-
250
- @manifest[:entity][:"#{name}_guid"] = association_guid
251
- @diff[:"#{name}_guid"] = association_guid
252
- assigned_value
253
- end
254
- end
255
-
256
- def to_many(plural, opts = {})
257
- to_many_relations[plural] = opts
258
-
259
- singular = plural.to_s.sub(/s$/, "").to_sym
260
-
261
- include QUERIES[singular]
262
-
263
- object = opts[:as] || singular
264
-
265
- kls = object.to_s.camelcase
266
-
267
- define_method(plural) do |*args|
268
- klass = CFoundry::V2.const_get(kls)
269
-
270
- opts, _ = args
271
- opts ||= {}
272
-
273
- if opts.empty? && cache = @cache[plural]
274
- return cache
275
- end
276
-
277
- if @manifest && @manifest[:entity].key?(plural) && opts.empty?
278
- objs = @manifest[:entity][plural]
279
-
280
- if query = opts[:query]
281
- find_by, find_val = query
282
- objs = objs.select { |o| o[:entity][find_by] == find_val }
283
- end
284
-
285
- res =
286
- objs.collect do |json|
287
- @client.send(:"make_#{object}", json)
288
- end
289
- else
290
- res =
291
- @client.send(
292
- :"#{klass.plural_object_name}_from",
293
- "/v2/#{plural_object_name}/#@guid/#{plural}",
294
- opts)
295
- end
296
-
297
- if opts.empty?
298
- @cache[plural] = res
299
- end
300
-
301
- res
302
- end
303
-
304
- define_method(:"#{plural}_url") do
305
- manifest[:entity][:"#{plural}_url"]
306
- end
307
-
308
- define_method(:"add_#{singular}") do |x|
309
- klass = self.class.objects[object]
310
-
311
- CFoundry::Validator.validate_type(x, klass)
312
-
313
- if cache = @cache[plural]
314
- cache << x unless cache.include?(x)
315
- end
316
-
317
- @client.base.put("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
318
- end
319
-
320
- define_method(:"remove_#{singular}") do |x|
321
- klass = self.class.objects[object]
322
-
323
- CFoundry::Validator.validate_type(x, klass)
324
-
325
- if cache = @cache[plural]
326
- cache.delete(x)
327
- end
328
-
329
- @client.base.delete("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
330
- end
331
-
332
- define_method(:"#{plural}=") do |xs|
333
- klass = self.class.objects[object]
334
-
335
- CFoundry::Validator.validate_type(xs, [klass])
336
-
337
- @manifest ||= {}
338
- @manifest[:entity] ||= {}
339
-
340
- old = @manifest[:entity][:"#{singular}_guids"]
341
- if old != xs.collect(&:guid)
342
- old_objs =
343
- @cache[plural] ||
344
- if all = @manifest[:entity][plural]
345
- all.collect do |m|
346
- klass.new(@client, m[:metadata][:guid], m)
347
- end
348
- elsif old
349
- old.collect { |id| klass.new(@client, id) }
350
- end
351
-
352
- @changes[plural] = [old_objs, xs]
353
- end
354
-
355
- @cache[plural] = xs
356
-
357
- @manifest[:entity][:"#{singular}_guids"] =
358
- @diff[:"#{singular}_guids"] = xs.collect(&:guid)
359
- end
360
- end
361
-
362
- def has_summary(actions = {})
363
- define_method(:summary) do
364
- @client.base.get("v2", plural_object_name, @guid, "summary", :accept => :json)
365
- end
366
-
367
- define_method(:summarize!) do |*args|
368
- body, _ = args
369
-
370
- body ||= summary
371
-
372
- body.each do |key, val|
373
- if act = actions[key]
374
- instance_exec(val, &act)
375
-
376
- elsif self.class.attributes[key]
377
- self.send(:"#{key}=", val)
378
-
379
- elsif self.class.to_many_relations[key]
380
- singular = key.to_s.sub(/s$/, "").to_sym
381
-
382
- vals = val.collect do |sub|
383
- obj = @client.send(singular, sub[:guid], true)
384
- obj.summarize! sub
385
- obj
386
- end
387
-
388
- self.send(:"#{key}=", vals)
389
-
390
- elsif self.class.to_one_relations[key]
391
- obj = @client.send(key, val[:guid], true)
392
- obj.summarize! val
393
-
394
- self.send(:"#{key}=", obj)
395
- end
396
- end
397
-
398
- nil
399
- end
400
- end
401
-
402
- def queryable_by(*names)
403
- klass = self
404
- singular = object_name
405
- plural = plural_object_name
406
-
407
- query = QUERIES[singular]
408
-
409
- query.module_eval do
410
- names.each do |name|
411
- define_method(:"#{singular}_by_#{name}") do |*args|
412
- send(:"#{plural}_by_#{name}", *args).first
413
- end
414
-
415
- define_method(:"#{plural}_by_#{name}") do |val, *args|
416
- options, _ = args
417
- options ||= {}
418
- options[:query] = [name, val]
419
-
420
- query_target(klass).send(plural, options)
421
- end
422
- end
423
- end
424
-
425
- const_set(:Queries, query)
426
-
427
- ClientMethods.module_eval do
428
- include query
429
- end
430
- end
431
-
432
73
  def self.params_from(args)
433
74
  options, _ = args
434
75
  options ||= {}
@@ -0,0 +1,49 @@
1
+ module CFoundry::V2::ModelMagic
2
+ module Attribute
3
+ def attribute(name, type, opts = {})
4
+ attributes[name] = opts
5
+ json_name = opts[:at] || name
6
+
7
+ default = opts[:default]
8
+
9
+ if has_default = opts.key?(:default)
10
+ defaults[name] = default
11
+ end
12
+
13
+ #
14
+ # def ATTRIBUTE
15
+ #
16
+ define_method(name) do
17
+ return @cache[name] if @cache.key?(name)
18
+ return nil unless persisted?
19
+
20
+ @cache[name] =
21
+ if manifest[:entity].key?(json_name)
22
+ manifest[:entity][json_name]
23
+ else
24
+ default
25
+ end
26
+ end
27
+
28
+ #
29
+ # def ATTRIBUTE=
30
+ #
31
+ define_method(:"#{name}=") do |val|
32
+ unless has_default && val == default
33
+ CFoundry::Validator.validate_type(val, type)
34
+ end
35
+
36
+ @cache[name] = val
37
+
38
+ @manifest ||= {}
39
+ @manifest[:entity] ||= {}
40
+
41
+ old = @manifest[:entity][json_name]
42
+ @changes[name] = [old, val] if old != val
43
+ @manifest[:entity][json_name] = val
44
+
45
+ @diff[json_name] = val
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,124 @@
1
+ module CFoundry
2
+ module V2
3
+ module ModelMagic
4
+ module ClientExtensions
5
+ def add_client_methods(klass)
6
+ singular = klass.object_name
7
+ plural = klass.plural_object_name
8
+
9
+ define_base_client_methods do
10
+ #
11
+ # def client.MODEL
12
+ #
13
+ define_method(singular) do |guid, *args|
14
+ get("v2", plural, guid,
15
+ :accept => :json,
16
+ :params => ModelMagic.params_from(args)
17
+ )
18
+ end
19
+
20
+ #
21
+ # def client.MODELs
22
+ #
23
+ define_method(plural) do |*args|
24
+ all_pages(
25
+ get("v2", plural,
26
+ :accept => :json,
27
+ :params => ModelMagic.params_from(args)
28
+ )
29
+ )
30
+ end
31
+ end
32
+
33
+
34
+ define_client_methods do
35
+ #
36
+ # def client.MODEL
37
+ #
38
+ define_method(singular) do |*args|
39
+ guid, partial, _ = args
40
+
41
+ x = klass.new(guid, self, nil, partial)
42
+
43
+ # when creating an object, automatically set the org/space
44
+ unless guid
45
+ if klass.scoped_organization && current_organization
46
+ x.send(:"#{klass.scoped_organization}=", current_organization)
47
+ end
48
+
49
+ if klass.scoped_space && current_space
50
+ x.send(:"#{klass.scoped_space}=", current_space)
51
+ end
52
+ end
53
+
54
+ x
55
+ end
56
+
57
+ #
58
+ # def client.MODELs
59
+ #
60
+ define_method(plural) do |*args|
61
+ # use current org/space
62
+ if klass.scoped_space && current_space
63
+ current_space.send(plural, *args)
64
+ elsif klass.scoped_organization && current_organization
65
+ current_organization.send(plural, *args)
66
+ else
67
+ @base.send(plural, *args).collect do |json|
68
+ send(:"make_#{singular}", json)
69
+ end
70
+ end
71
+ end
72
+
73
+ #
74
+ # def client.MODEL_from
75
+ #
76
+ define_method(:"#{singular}_from") do |path, *args|
77
+ send(
78
+ :"make_#{singular}",
79
+ @base.get(
80
+ path,
81
+ :accept => :json,
82
+ :params => ModelMagic.params_from(args)))
83
+ end
84
+
85
+ #
86
+ # def client.MODELs_from
87
+ #
88
+ define_method(:"#{plural}_from") do |path, *args|
89
+ objs = @base.all_pages(
90
+ @base.get(
91
+ path,
92
+ :accept => :json,
93
+ :params => ModelMagic.params_from(args)))
94
+
95
+ objs.collect do |json|
96
+ send(:"make_#{singular}", json)
97
+ end
98
+ end
99
+
100
+ #
101
+ # def client.make_MODEL
102
+ #
103
+ define_method(:"make_#{singular}") do |json|
104
+ klass.new(
105
+ json[:metadata][:guid],
106
+ self,
107
+ json)
108
+ end
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ def define_client_methods(&blk)
115
+ ClientMethods.module_eval(&blk)
116
+ end
117
+
118
+ def define_base_client_methods(&blk)
119
+ BaseClientMethods.module_eval(&blk)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,49 @@
1
+ module CFoundry::V2::ModelMagic
2
+ module HasSummary
3
+ def has_summary(actions = {})
4
+ #
5
+ # def summary
6
+ #
7
+ define_method(:summary) do
8
+ @client.base.get("v2", plural_object_name, @guid, "summary", :accept => :json)
9
+ end
10
+
11
+ #
12
+ # def summarize!
13
+ #
14
+ define_method(:summarize!) do |*args|
15
+ body, _ = args
16
+
17
+ body ||= summary
18
+
19
+ body.each do |key, val|
20
+ if act = actions[key]
21
+ instance_exec(val, &act)
22
+
23
+ elsif self.class.attributes[key]
24
+ self.send(:"#{key}=", val)
25
+
26
+ elsif self.class.to_many_relations[key]
27
+ singular = key.to_s.sub(/s$/, "").to_sym
28
+
29
+ vals = val.collect do |sub|
30
+ obj = @client.send(singular, sub[:guid], true)
31
+ obj.summarize! sub
32
+ obj
33
+ end
34
+
35
+ self.send(:"#{key}=", vals)
36
+
37
+ elsif self.class.to_one_relations[key]
38
+ obj = @client.send(key, val[:guid], true)
39
+ obj.summarize! val
40
+
41
+ self.send(:"#{key}=", obj)
42
+ end
43
+ end
44
+
45
+ nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ module CFoundry::V2
2
+ module ModelMagic::QueryableBy
3
+ def queryable_by(*names)
4
+ klass = self
5
+ singular = object_name
6
+ plural = plural_object_name
7
+
8
+ query = ::CFoundry::V2::QUERIES[singular]
9
+
10
+ query.module_eval do
11
+ names.each do |name|
12
+ #
13
+ # def MODEL_by_ATTRIBUTE
14
+ #
15
+ define_method(:"#{singular}_by_#{name}") do |*args|
16
+ send(:"#{plural}_by_#{name}", *args).first
17
+ end
18
+
19
+ #
20
+ # def MODELs_by_ATTRIBUTE
21
+ #
22
+ define_method(:"#{plural}_by_#{name}") do |val, *args|
23
+ options, _ = args
24
+ options ||= {}
25
+ options[:query] = [name, val]
26
+
27
+ query_target(klass).send(plural, options)
28
+ end
29
+ end
30
+ end
31
+
32
+ const_set(:Queries, query)
33
+
34
+ ClientMethods.module_eval do
35
+ include query
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,138 @@
1
+ module CFoundry::V2::ModelMagic
2
+ module ToMany
3
+ def to_many(plural, opts = {})
4
+ to_many_relations[plural] = opts
5
+
6
+ singular = plural.to_s.sub(/s$/, "").to_sym
7
+
8
+ include ::CFoundry::V2::QUERIES[singular]
9
+
10
+ object = opts[:as] || singular
11
+
12
+ kls = object.to_s.camelcase
13
+
14
+ #
15
+ # def MODELs
16
+ #
17
+ define_method(plural) do |*args|
18
+ klass = CFoundry::V2.const_get(kls)
19
+
20
+ opts, _ = args
21
+ opts ||= {}
22
+
23
+ if opts.empty? && cache = @cache[plural]
24
+ return cache
25
+ end
26
+
27
+ if @manifest && @manifest[:entity].key?(plural) && opts.empty?
28
+ objs = @manifest[:entity][plural]
29
+
30
+ if query = opts[:query]
31
+ find_by, find_val = query
32
+ objs = objs.select { |o| o[:entity][find_by] == find_val }
33
+ end
34
+
35
+ res =
36
+ objs.collect do |json|
37
+ @client.send(:"make_#{object}", json)
38
+ end
39
+ else
40
+ res =
41
+ @client.send(
42
+ :"#{klass.plural_object_name}_from",
43
+ "/v2/#{plural_object_name}/#@guid/#{plural}",
44
+ opts)
45
+ end
46
+
47
+ if opts.empty?
48
+ @cache[plural] = res
49
+ end
50
+
51
+ res
52
+ end
53
+
54
+ #
55
+ # def MODELs_url
56
+ #
57
+ define_method(:"#{plural}_url") do
58
+ manifest[:entity][:"#{plural}_url"]
59
+ end
60
+
61
+ #
62
+ # def add_MODEL
63
+ #
64
+ define_method(:"add_#{singular}") do |x|
65
+ klass = self.class.objects[object]
66
+
67
+ CFoundry::Validator.validate_type(x, klass)
68
+
69
+ if cache = @cache[plural]
70
+ cache << x unless cache.include?(x)
71
+ end
72
+
73
+ @client.base.put("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
74
+ end
75
+
76
+ #
77
+ # def create_MODEL
78
+ #
79
+ define_method("create_#{singular}") do |*args|
80
+ associated_instance = @client.send(:"#{singular}")
81
+ args.first.each do |name, value|
82
+ associated_instance.send("#{name}=", value)
83
+ end if args.first.is_a? Hash
84
+
85
+ associated_instance.create!
86
+ self.send(:"add_#{singular}", associated_instance)
87
+ associated_instance
88
+ end
89
+
90
+ #
91
+ # def remove_MODEL
92
+ #
93
+ define_method(:"remove_#{singular}") do |x|
94
+ klass = self.class.objects[object]
95
+
96
+ CFoundry::Validator.validate_type(x, klass)
97
+
98
+ if cache = @cache[plural]
99
+ cache.delete(x)
100
+ end
101
+
102
+ @client.base.delete("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
103
+ end
104
+
105
+ #
106
+ # def MODELs=
107
+ #
108
+ define_method(:"#{plural}=") do |xs|
109
+ klass = self.class.objects[object]
110
+
111
+ CFoundry::Validator.validate_type(xs, [klass])
112
+
113
+ @manifest ||= {}
114
+ @manifest[:entity] ||= {}
115
+
116
+ old = @manifest[:entity][:"#{singular}_guids"]
117
+ if old != xs.collect(&:guid)
118
+ old_objs =
119
+ @cache[plural] ||
120
+ if all = @manifest[:entity][plural]
121
+ all.collect do |m|
122
+ klass.new(@client, m[:metadata][:guid], m)
123
+ end
124
+ elsif old
125
+ old.collect { |id| klass.new(@client, id) }
126
+ end
127
+
128
+ @changes[plural] = [old_objs, xs]
129
+ end
130
+
131
+ @cache[plural] = xs
132
+
133
+ @manifest[:entity][:"#{singular}_guids"] =
134
+ @diff[:"#{singular}_guids"] = xs.collect(&:guid)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,81 @@
1
+ module CFoundry::V2::ModelMagic
2
+ module ToOne
3
+ def to_one(name, opts = {})
4
+ to_one_relations[name] = opts
5
+
6
+ association_name = opts[:as] || name
7
+ default = opts[:default]
8
+
9
+ if has_default = opts.key?(:default)
10
+ defaults[:"#{name}_guid"] = default
11
+ end
12
+
13
+ #
14
+ # def MODEL
15
+ #
16
+ define_method(name) do
17
+ return @cache[name] if @cache.key?(name)
18
+ return @client.send(name) unless persisted?
19
+
20
+ @cache[name] =
21
+ if @manifest && @manifest[:entity].key?(name)
22
+ @client.send(:"make_#{association_name}", @manifest[:entity][name])
23
+ elsif url = send("#{name}_url")
24
+ @client.send(:"#{association_name}_from", url)
25
+ else
26
+ default
27
+ end
28
+ end
29
+
30
+ #
31
+ # def create_MODEL
32
+ #
33
+ define_method("create_#{name}") do |*args|
34
+ associated_instance = @client.send(:"#{association_name}")
35
+ args.first.each do |name, value|
36
+ associated_instance.send("#{name}=", value)
37
+ end if args.first.is_a? Hash
38
+
39
+ associated_instance.create!
40
+ self.send("#{name}=", associated_instance)
41
+ end
42
+
43
+ #
44
+ # def MODEL_url
45
+ #
46
+ define_method(:"#{name}_url") do
47
+ manifest[:entity][:"#{name}_url"]
48
+ end
49
+
50
+ #
51
+ # def MODEL=
52
+ #
53
+ define_method(:"#{name}=") do |assigned_value|
54
+ klass = self.class.objects[association_name]
55
+
56
+ unless has_default && assigned_value == default
57
+ CFoundry::Validator.validate_type(assigned_value, klass)
58
+ end
59
+
60
+ @manifest ||= {}
61
+ @manifest[:entity] ||= {}
62
+
63
+ old_guid = @manifest[:entity][:"#{name}_guid"]
64
+ association_guid = assigned_value ? assigned_value.guid : nil
65
+
66
+ if old_guid != (association_guid)
67
+ old_obj =
68
+ @cache[name] || klass.new(@client, old_guid, @manifest[:entity][name])
69
+
70
+ @changes[name] = [old_obj, assigned_value]
71
+ end
72
+
73
+ @cache[name] = assigned_value
74
+
75
+ @manifest[:entity][:"#{name}_guid"] = association_guid
76
+ @diff[:"#{name}_guid"] = association_guid
77
+ assigned_value
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,4 +1,4 @@
1
1
  module CFoundry # :nodoc:
2
2
  # CFoundry library version number.
3
- VERSION = "1.4.0".freeze
3
+ VERSION = "1.5.0".freeze
4
4
  end
@@ -1,10 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  module CFoundry::V2
4
- class Associated < FakeModel
5
- attribute :attribute, String
6
- end
7
-
8
4
  describe ModelMagic do
9
5
  let(:client) { fake_client }
10
6
  let(:mymodel) { fake_model }
@@ -122,96 +118,5 @@ module CFoundry::V2
122
118
  end
123
119
  end
124
120
  end
125
-
126
- describe 'to_one relationships' do
127
- describe 'writing' do
128
- let!(:mymodel) { fake_model { to_one :foo } }
129
- let!(:othermodel) { fake_model :foo }
130
-
131
- let(:myobject) { mymodel.new(nil, client).fake }
132
- let(:otherobject) { othermodel.new(nil, client).fake }
133
-
134
- subject { myobject.foo = otherobject }
135
-
136
- it "sets the GUID in the manifest to the object's GUID" do
137
- expect { subject }.to change {
138
- myobject.manifest[:entity][:foo_guid]
139
- }.to(otherobject.guid)
140
- end
141
-
142
- it "tracks internal changes in the diff" do
143
- expect { subject }.to change { myobject.diff }.to(
144
- :foo_guid => otherobject.guid)
145
- end
146
-
147
- it "tracks high-level changes in .changes" do
148
- before = myobject.foo
149
- expect { subject }.to change { myobject.changes }.to(
150
- :foo => [before, otherobject])
151
- end
152
-
153
- it "returns the assigned value" do
154
- myobject.send(:foo=, otherobject).should == otherobject
155
- end
156
-
157
- context "when there is a default" do
158
- let(:mymodel) { fake_model { to_one :foo, :default => nil } }
159
-
160
- subject { myobject.foo = nil }
161
-
162
- it "allows setting to the default" do
163
- myobject.foo = otherobject
164
-
165
- expect { subject }.to change {
166
- myobject.manifest[:entity][:foo_guid]
167
- }.from(otherobject.guid).to(nil)
168
- end
169
- end
170
- end
171
-
172
- describe 'associated create' do
173
- let!(:model) { fake_model { to_one :associated } }
174
- let(:instance) { model.new(nil, client).fake }
175
- let!(:request) { WebMock.stub_request(:post, /v2\/associated/).to_return(:body => {:metadata => {:guid => "thing"}}.to_json) }
176
-
177
- it 'returns a new associated object' do
178
- instance.create_associated.should be_a(Associated)
179
- end
180
-
181
- it 'sets the relation' do
182
- created = instance.create_associated
183
- instance.associated.should == created
184
- end
185
-
186
- context 'with attributes for the association' do
187
- it 'sets these attributes on the association' do
188
- created = instance.create_associated(:attribute => 'value')
189
- created.attribute.should == 'value'
190
- end
191
- end
192
-
193
- it 'calls out to cloud_controller' do
194
- instance.create_associated
195
- request.should have_been_requested
196
- end
197
-
198
- context 'when creation fails' do
199
- let!(:request) { WebMock.stub_request(:post, /v2\/associated/).to_raise(:not_authorized) }
200
-
201
- it 'raises an exception' do
202
- expect { instance.create_associated }.to raise_error(StandardError)
203
- end
204
- end
205
- end
206
- end
207
-
208
- describe 'summarization for an arbitrary model' do
209
- let(:mymodel) { fake_model { attribute :foo, :string } }
210
- let(:summary_attributes) { {:foo => "abcd"} }
211
-
212
- subject { myobject }
213
-
214
- it_behaves_like 'a summarizeable model'
215
- end
216
121
  end
217
122
  end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry::V2
4
+ describe ModelMagic do
5
+ let(:client) { fake_client }
6
+ let(:guid) { random_string("my-object-guid") }
7
+ let(:myobject) { mymodel.new(guid, client) }
8
+
9
+ describe 'summarization for an arbitrary model' do
10
+ let(:mymodel) { fake_model { attribute :foo, :string } }
11
+ let(:summary_attributes) { {:foo => "abcd"} }
12
+
13
+ subject { myobject }
14
+
15
+ it_behaves_like 'a summarizeable model'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry::V2
4
+ include ModelMagic::ToMany
5
+
6
+ class AssociatedModel < FakeModel
7
+ attribute :attribute, String
8
+ end
9
+
10
+ describe ModelMagic::ToMany do
11
+ let(:client) { fake_client }
12
+ let(:mymodel) { fake_model }
13
+ let(:guid) { random_string("my-object-guid") }
14
+ let(:myobject) { mymodel.new(guid, client) }
15
+
16
+ describe "to_many relationships" do
17
+ describe "associated create" do
18
+ let!(:model) { fake_model { to_many :associated_models } }
19
+ let(:instance) { model.new(nil, client).fake }
20
+ let!(:create_request) { WebMock.stub_request(:post, /v2\/associated_model/).to_return(:body => {:metadata => {:guid => "thing"}}.to_json) }
21
+ let!(:add_request) { WebMock.stub_request(:put, /v2\/my_fake_models\/.*\/associated_models/).to_return(:body => {}.to_json) }
22
+
23
+ before do
24
+ stub_request(:get, /v2\/my_fake_models\/.*\/associated_models/)
25
+ instance.associated_models = []
26
+ end
27
+
28
+ it "returns a new associated object" do
29
+ instance.create_associated_model.should be_a(AssociatedModel)
30
+ end
31
+
32
+ it "sets the relation" do
33
+ created = instance.create_associated_model
34
+ instance.associated_models.should include(created)
35
+ end
36
+
37
+ context "with attributes for the association" do
38
+ it "sets these attributes on the association" do
39
+ created = instance.create_associated_model(:attribute => "value")
40
+ created.attribute.should == "value"
41
+ end
42
+ end
43
+
44
+ it "calls out to cloud_controller" do
45
+ instance.create_associated_model
46
+ create_request.should have_been_requested
47
+ end
48
+
49
+ context "when creation fails" do
50
+ let!(:create_request) { WebMock.stub_request(:post, /v2\/associated_model/).to_raise(:not_authorized) }
51
+
52
+ it "raises an exception" do
53
+ expect { instance.create_associated_model }.to raise_error(StandardError)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry::V2
4
+ include ModelMagic::ToOne
5
+ class Associated < FakeModel
6
+ attribute :attribute, String
7
+ end
8
+
9
+ describe ModelMagic::ToOne do
10
+ let(:client) { fake_client }
11
+ let(:mymodel) { fake_model }
12
+ let(:guid) { random_string("my-object-guid") }
13
+ let(:myobject) { mymodel.new(guid, client) }
14
+
15
+ describe 'to_one relationships' do
16
+ describe 'writing' do
17
+ let!(:mymodel) { fake_model { to_one :foo } }
18
+ let!(:othermodel) { fake_model :foo }
19
+
20
+ let(:myobject) { mymodel.new(nil, client).fake }
21
+ let(:otherobject) { othermodel.new(nil, client).fake }
22
+
23
+ subject { myobject.foo = otherobject }
24
+
25
+ it "sets the GUID in the manifest to the object's GUID" do
26
+ expect { subject }.to change {
27
+ myobject.manifest[:entity][:foo_guid]
28
+ }.to(otherobject.guid)
29
+ end
30
+
31
+ it "tracks internal changes in the diff" do
32
+ expect { subject }.to change { myobject.diff }.to(
33
+ :foo_guid => otherobject.guid)
34
+ end
35
+
36
+ it "tracks high-level changes in .changes" do
37
+ before = myobject.foo
38
+ expect { subject }.to change { myobject.changes }.to(
39
+ :foo => [before, otherobject])
40
+ end
41
+
42
+ it "returns the assigned value" do
43
+ myobject.send(:foo=, otherobject).should == otherobject
44
+ end
45
+
46
+ context "when there is a default" do
47
+ let(:mymodel) { fake_model { to_one :foo, :default => nil } }
48
+
49
+ subject { myobject.foo = nil }
50
+
51
+ it "allows setting to the default" do
52
+ myobject.foo = otherobject
53
+
54
+ expect { subject }.to change {
55
+ myobject.manifest[:entity][:foo_guid]
56
+ }.from(otherobject.guid).to(nil)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe 'associated create' do
62
+ let!(:model) { fake_model { to_one :associated } }
63
+ let(:instance) { model.new(nil, client).fake }
64
+ let!(:request) { WebMock.stub_request(:post, /v2\/associated/).to_return(:body => {:metadata => {:guid => "thing"}}.to_json) }
65
+
66
+ it 'returns a new associated object' do
67
+ instance.create_associated.should be_a(Associated)
68
+ end
69
+
70
+ it 'sets the relation' do
71
+ created = instance.create_associated
72
+ instance.associated.should == created
73
+ end
74
+
75
+ context 'with attributes for the association' do
76
+ it 'sets these attributes on the association' do
77
+ created = instance.create_associated(:attribute => 'value')
78
+ created.attribute.should == 'value'
79
+ end
80
+ end
81
+
82
+ it 'calls out to cloud_controller' do
83
+ instance.create_associated
84
+ request.should have_been_requested
85
+ end
86
+
87
+ context 'when creation fails' do
88
+ let!(:request) { WebMock.stub_request(:post, /v2\/associated/).to_raise(:not_authorized) }
89
+
90
+ it 'raises an exception' do
91
+ expect { instance.create_associated }.to raise_error(StandardError)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfoundry
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-05-28 00:00:00.000000000 Z
13
+ date: 2013-05-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multipart-post
@@ -261,6 +261,12 @@ files:
261
261
  - lib/cfoundry/v2/client.rb
262
262
  - lib/cfoundry/v2/domain.rb
263
263
  - lib/cfoundry/v2/model.rb
264
+ - lib/cfoundry/v2/model_magic/attribute.rb
265
+ - lib/cfoundry/v2/model_magic/client_extensions.rb
266
+ - lib/cfoundry/v2/model_magic/has_summary.rb
267
+ - lib/cfoundry/v2/model_magic/queryable_by.rb
268
+ - lib/cfoundry/v2/model_magic/to_many.rb
269
+ - lib/cfoundry/v2/model_magic/to_one.rb
264
270
  - lib/cfoundry/v2/model_magic.rb
265
271
  - lib/cfoundry/v2/organization.rb
266
272
  - lib/cfoundry/v2/quota_definition.rb
@@ -306,7 +312,10 @@ files:
306
312
  - spec/cfoundry/v2/base_spec.rb
307
313
  - spec/cfoundry/v2/client_spec.rb
308
314
  - spec/cfoundry/v2/domain_spec.rb
309
- - spec/cfoundry/v2/model_magic_spec.rb
315
+ - spec/cfoundry/v2/model_magic/model_magic/attribute_spec.rb
316
+ - spec/cfoundry/v2/model_magic/model_magic/has_summary_spec.rb
317
+ - spec/cfoundry/v2/model_magic/model_magic/to_many_spec.rb
318
+ - spec/cfoundry/v2/model_magic/model_magic/to_one_spec.rb
310
319
  - spec/cfoundry/v2/model_spec.rb
311
320
  - spec/cfoundry/v2/organization_spec.rb
312
321
  - spec/cfoundry/v2/quota_definition_spec.rb
@@ -390,7 +399,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
390
399
  version: '0'
391
400
  segments:
392
401
  - 0
393
- hash: 731683098158861932
402
+ hash: 3516132401454604907
394
403
  required_rubygems_version: !ruby/object:Gem::Requirement
395
404
  none: false
396
405
  requirements:
@@ -430,7 +439,10 @@ test_files:
430
439
  - spec/cfoundry/v2/base_spec.rb
431
440
  - spec/cfoundry/v2/client_spec.rb
432
441
  - spec/cfoundry/v2/domain_spec.rb
433
- - spec/cfoundry/v2/model_magic_spec.rb
442
+ - spec/cfoundry/v2/model_magic/model_magic/attribute_spec.rb
443
+ - spec/cfoundry/v2/model_magic/model_magic/has_summary_spec.rb
444
+ - spec/cfoundry/v2/model_magic/model_magic/to_many_spec.rb
445
+ - spec/cfoundry/v2/model_magic/model_magic/to_one_spec.rb
434
446
  - spec/cfoundry/v2/model_spec.rb
435
447
  - spec/cfoundry/v2/organization_spec.rb
436
448
  - spec/cfoundry/v2/quota_definition_spec.rb