cfoundry 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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