mongoid_alize 0.2.0 → 0.3.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 (32) hide show
  1. data/config/locales/en.yml +1 -0
  2. data/lib/mongoid/alize/callback.rb +48 -13
  3. data/lib/mongoid/alize/callbacks/from/many.rb +5 -5
  4. data/lib/mongoid/alize/callbacks/from/one.rb +14 -31
  5. data/lib/mongoid/alize/errors/invalid_configuration.rb +16 -0
  6. data/lib/mongoid/alize/from_callback.rb +4 -2
  7. data/lib/mongoid/alize/instance_helpers.rb +25 -0
  8. data/lib/mongoid/alize/macros.rb +65 -42
  9. data/lib/mongoid/alize/to_callback.rb +104 -9
  10. data/lib/mongoid_alize.rb +3 -7
  11. data/spec/app/models/head.rb +17 -1
  12. data/spec/app/models/mock_object.rb +6 -0
  13. data/spec/app/models/person.rb +16 -0
  14. data/spec/helpers/macros_helper.rb +11 -7
  15. data/spec/mongoid/alize/callback_spec.rb +62 -6
  16. data/spec/mongoid/alize/callbacks/from/one_spec.rb +41 -43
  17. data/spec/mongoid/alize/callbacks/to/many_from_many_spec.rb +23 -17
  18. data/spec/mongoid/alize/callbacks/to/many_from_one_spec.rb +158 -60
  19. data/spec/mongoid/alize/callbacks/to/one_from_many_spec.rb +110 -42
  20. data/spec/mongoid/alize/callbacks/to/one_from_one_spec.rb +167 -47
  21. data/spec/mongoid/alize/instance_helpers_spec.rb +36 -0
  22. data/spec/mongoid/alize/macros_spec.rb +90 -17
  23. data/spec/mongoid/alize/to_callback_spec.rb +87 -18
  24. data/spec/mongoid_alize_spec.rb +245 -26
  25. data/spec/spec_helper.rb +3 -1
  26. metadata +6 -8
  27. data/lib/mongoid/alize/callbacks/to/many_from_many.rb +0 -16
  28. data/lib/mongoid/alize/callbacks/to/many_from_one.rb +0 -15
  29. data/lib/mongoid/alize/callbacks/to/one_from_many.rb +0 -15
  30. data/lib/mongoid/alize/callbacks/to/one_from_one.rb +0 -15
  31. data/lib/mongoid/alize/to_many_callback.rb +0 -50
  32. data/lib/mongoid/alize/to_one_callback.rb +0 -43
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::Alize::InstanceHelpers do
4
+
5
+ def from_klass
6
+ Mongoid::Alize::Callbacks::From::One
7
+ end
8
+
9
+ def to_klass
10
+ Mongoid::Alize::ToCallback
11
+ end
12
+
13
+ before do
14
+ @head =
15
+ Head.new(person:
16
+ @person = Person.create(:name => @name = "Bob"))
17
+ end
18
+
19
+ describe "#denormalize_from_all" do
20
+ it "should run the alize callbacks" do
21
+ Head.alize_from_callbacks <<
22
+ callback = from_klass.new(Head, :person, [:name])
23
+ mock(@head).denormalize_from_person
24
+ @head.denormalize_from_all
25
+ end
26
+ end
27
+
28
+ describe "#denormalize_to_all" do
29
+ it "should run the alize callbacks" do
30
+ Person.alize_to_callbacks <<
31
+ callback = to_klass.new(Person, :head, [:size])
32
+ mock(@person).denormalize_to_head
33
+ @person.denormalize_to_all
34
+ end
35
+ end
36
+ end
@@ -1,64 +1,137 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongoid::Alize::Macros do
4
- describe "#alize" do
4
+ def person_default_fields
5
+ ["name", "created_at", "want_ids", "seen_by_id"]
6
+ end
7
+
8
+ def head_default_fields
9
+ ["size", "weight", "person_id", "captor_id", "wanted_by_ids"]
10
+ end
11
+
12
+ describe "#alize_to and #alize_from" do
5
13
  describe "with a belongs_to" do
6
14
  it_should_set_callbacks(Head, Person,
7
15
  :person, :head,
8
- fns::One, tns::OneFromOne)
16
+ fns::One, tns)
9
17
  end
10
18
 
11
19
  describe "with a has_one" do
12
20
  it_should_set_callbacks(Person, Head,
13
21
  :head, :person,
14
- fns::One, tns::OneFromOne)
22
+ fns::One, tns)
15
23
  end
16
24
 
17
25
  describe "with a has_many from the belongs_to side" do
18
26
  it_should_set_callbacks(Head, Person,
19
27
  :captor, :heads,
20
- fns::One, tns::OneFromMany)
28
+ fns::One, tns)
21
29
  end
22
30
 
23
31
  describe "with a has_many from the has_many side" do
24
32
  it_should_set_callbacks(Head, Person,
25
33
  :sees, :seen_by,
26
- fns::Many, tns::ManyFromOne)
34
+ fns::Many, tns)
27
35
  end
28
36
 
29
37
  describe "with a has_and_belongs_to_many" do
30
38
  it_should_set_callbacks(Head, Person,
31
39
  :wanted_by, :wants,
32
- fns::Many, tns::ManyFromMany)
40
+ fns::Many, tns)
33
41
  end
34
42
 
35
- describe "when no inverse is present" do
36
- it "should add only a from and not a to callback" do
37
- dont_allow(Mongoid::Alize::Callbacks::To::OneFromOne).new
38
- Head.alize(:admirer)
43
+ describe "#alize" do
44
+ it "should call alize_from" do
45
+ mock(Head).alize_from(:person, :name)
46
+ Head.alize(:person, :name)
47
+ end
48
+
49
+ it "should call alize_to if relation is not polymorphic" do
50
+ mock(Person).alize_to(:head, :name)
51
+ Head.alize(:person, :name)
52
+ end
53
+
54
+ describe "with a polymorphic association" do
55
+ it "should attach an inverse callback to the parent side" do
56
+ Person.relations["nearest_head"].should be_polymorphic
57
+ Person.relations["nearest_head"].should_not be_stores_foreign_key
58
+ Person.relations["nearest_head"].klass.should == Head
59
+ mock.proxy(Mongoid::Alize::ToCallback).new(Head, :nearest, head_default_fields)
60
+ Person.alize(:nearest_head)
61
+ end
62
+
63
+ it "should not attach a callback on the child side" do
64
+ Head.relations["nearest"].should be_polymorphic
65
+ Head.relations["nearest"].should be_stores_foreign_key
66
+ dont_allow(Mongoid::Alize::ToCallback).new
67
+ Head.alize(:nearest)
68
+ end
69
+ end
70
+
71
+ describe "when no inverse is present" do
72
+ it "should add only a from callback" do
73
+ Head.relations["admirer"].inverse.should be_nil
74
+ dont_allow(Mongoid::Alize::ToCallback).new
75
+ Head.alize(:admirer)
76
+ end
39
77
  end
40
78
  end
41
79
 
42
- describe "fields" do
80
+ describe "#alize_to" do
43
81
  describe "with fields supplied" do
44
82
  it "should use them" do
45
- dont_allow(Head).default_alize_fields
46
- Head.alize(:person, :name)
83
+ mock.proxy(Mongoid::Alize::ToCallback).new(Person, :head, [:foo, :bar])
84
+ Person.alize_to(:head, :foo, :bar)
47
85
  end
48
86
  end
49
87
 
50
88
  describe "with no fields supplied" do
51
89
  it "should use the default alize fields" do
52
- mock(Head).default_alize_fields(:person) { [:name] }
53
- Head.alize(:person)
90
+ mock.proxy(Mongoid::Alize::ToCallback).new(Person, :head, person_default_fields)
91
+ Person.alize_to(:head)
92
+ end
93
+ end
94
+
95
+ describe "with a block supplied" do
96
+ it "should use the block supplied as fields in the options hash" do
97
+ blk = lambda {}
98
+ mock.proxy(Mongoid::Alize::ToCallback).new(Person, :head, blk)
99
+ Person.alize_to(:head, :foo, :fields => blk)
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#alize_from" do
105
+ describe "with fields supplied" do
106
+ it "should use them" do
107
+ mock.proxy(Mongoid::Alize::Callbacks::From::One).new(
108
+ Head, :person, [:foo, :bar])
109
+ Head.alize_from(:person, :foo, :bar)
110
+ end
111
+ end
112
+
113
+ describe "with no fields supplied" do
114
+ it "should use the default alize fields" do
115
+ mock.proxy(Mongoid::Alize::Callbacks::From::One).new(
116
+ Head, :person, person_default_fields)
117
+ Head.alize_from(:person)
118
+ end
119
+ end
120
+
121
+ describe "with a block supplied" do
122
+ it "should use the block supplied as fields in the options hash" do
123
+ blk = lambda {}
124
+ mock.proxy(Mongoid::Alize::Callbacks::From::One).new(
125
+ Head, :person, blk)
126
+ Head.alize_from(:person, :foo, :fields => blk)
54
127
  end
55
128
  end
56
129
  end
57
130
 
58
131
  describe "default_alize_fields" do
59
132
  it "should return an array of all non-internal field names (e.g. not _type or _id)" do
60
- Head.default_alize_fields(:person).should ==
61
- ["name", "created_at", "want_ids", "seen_by_id"]
133
+ Head.default_alize_fields.should == head_default_fields
134
+ Person.default_alize_fields.should == person_default_fields
62
135
  end
63
136
  end
64
137
  end
@@ -1,38 +1,59 @@
1
1
  require 'spec_helper'
2
2
 
3
- class Mongoid::Alize::SpecToCallback < Mongoid::Alize::ToCallback
4
- def define_callback
5
- klass.class_eval <<-CALLBACK
6
- def _denormalize_to_head
7
- end
8
- CALLBACK
9
- end
10
-
11
- def define_destroy_callback
12
- klass.class_eval <<-CALLBACK
13
- def _denormalize_destroy_to_head
14
- end
15
- CALLBACK
16
- end
17
- end
18
-
19
3
  describe Mongoid::Alize::ToCallback do
20
4
  def klass
21
- Mongoid::Alize::SpecToCallback
5
+ Mongoid::Alize::ToCallback
22
6
  end
23
7
 
24
8
  def args
25
- [Person, :head, [:name, :location, :created_at]]
9
+ [Person, :head, [:name]]
26
10
  end
27
11
 
28
12
  def new_callback
29
13
  klass.new(*args)
30
14
  end
31
15
 
16
+ def define_and_create(callback_name=:define_callback)
17
+ @callback = new_callback
18
+ @callback.send(:define_fields)
19
+ create_models
20
+ @callback.send(callback_name)
21
+ end
22
+
32
23
  before do
33
24
  @callback = new_callback
34
25
  end
35
26
 
27
+ describe "names" do
28
+ it "should assign a destroy callback name" do
29
+ @callback.destroy_callback_name.should == "_denormalize_destroy_to_head"
30
+ end
31
+
32
+ it "should assign an aliased destroy callback name" do
33
+ @callback.aliased_destroy_callback_name.should == "denormalize_destroy_to_head"
34
+ end
35
+
36
+ it "should assign a prefixed name from the inverse if present" do
37
+ @callback.inverse_klass.should == Head
38
+ @callback.inverse_relation.should == :person
39
+ @callback.prefixed_name.should == ":person_fields"
40
+ end
41
+
42
+ it "should compute the name on the fly if the inverse is not present" do
43
+ @callback = klass.new(Head, :nearest, [:name])
44
+ @callback.inverse_klass.should be_nil
45
+ @callback.inverse_relation.should be_nil
46
+ @callback.prefixed_name.should =~ /relation/
47
+ end
48
+ end
49
+
50
+ describe "#define_fields" do
51
+ it "should define the fields method" do
52
+ mock(@callback).define_fields_method
53
+ @callback.send(:define_fields)
54
+ end
55
+ end
56
+
36
57
  describe "#set_callback" do
37
58
  it "should set a callback on the klass" do
38
59
  mock(@callback.klass).set_callback(:save, :after, "denormalize_to_head")
@@ -62,6 +83,7 @@ describe Mongoid::Alize::ToCallback do
62
83
  describe "#alias_destroy_callback" do
63
84
  it "should alias the destroy callback on the klass" do
64
85
  mock(@callback.klass).alias_method("denormalize_destroy_to_head", "_denormalize_destroy_to_head")
86
+ mock(@callback.klass).public("denormalize_destroy_to_head")
65
87
  @callback.send(:alias_destroy_callback)
66
88
  end
67
89
 
@@ -71,4 +93,51 @@ describe Mongoid::Alize::ToCallback do
71
93
  @callback.send(:alias_destroy_callback)
72
94
  end
73
95
  end
96
+
97
+ describe "not modifying frozen hashes" do
98
+ def create_models
99
+ @person = Person.create!(:name => @name = "George")
100
+ @head = Head.create(:person => @person)
101
+ end
102
+
103
+ def person_fields
104
+ { :name => @name }
105
+ end
106
+
107
+ before do
108
+ Head.class_eval do
109
+ field :person_fields, :type => Hash, :default => {}
110
+ end
111
+ define_and_create(:define_destroy_callback)
112
+ end
113
+
114
+ describe "#define_callback" do
115
+ def run_callback
116
+ @person.send(:_denormalize_to_head)
117
+ end
118
+
119
+ before do
120
+ define_and_create(:define_callback)
121
+ end
122
+
123
+ it "should not modify object frozen for deletion" do
124
+ @head.destroy
125
+ run_callback
126
+ @head.person_fields.should == {}
127
+ end
128
+ end
129
+
130
+ describe "#define_destroy_callback" do
131
+ def run_callback
132
+ @person.send(:_denormalize_destroy_to_head)
133
+ end
134
+
135
+ it "should not modify object frozen for deletion" do
136
+ @head.person_fields = person_fields
137
+ @head.destroy
138
+ run_callback
139
+ @head.person_fields.should == person_fields
140
+ end
141
+ end
142
+ end
74
143
  end
@@ -24,8 +24,10 @@ describe Mongoid::Alize do
24
24
  end
25
25
 
26
26
  def assert_head
27
- @head.person_name.should == @name
28
- @head.person_location.should == "Paris"
27
+ @head.person_fields.should == {
28
+ "name" => @name,
29
+ "location" => "Paris"
30
+ }
29
31
  end
30
32
 
31
33
  it "should pull data from person on create" do
@@ -42,9 +44,9 @@ describe Mongoid::Alize do
42
44
 
43
45
  it "should not pull data from an unchanged person on save" do
44
46
  @head.save!
45
- @head.person_name = "Cowboy"
47
+ @head.person_fields["name"] = "Cowboy"
46
48
  @head.save!
47
- @head.person_name.should == "Cowboy"
49
+ @head.person_fields["name"].should == "Cowboy"
48
50
  end
49
51
 
50
52
  it "should push data to head" do
@@ -53,10 +55,9 @@ describe Mongoid::Alize do
53
55
  end
54
56
 
55
57
  it "should nillify person fields in head when person is destroyed" do
56
- @head.update_attributes!(:person_name => "Old Gregg")
58
+ @head.update_attributes!(:person_fields => { "name" => "Old Gregg", "location" => "Paris" })
57
59
  @person.destroy
58
- @head.person_name.should be_nil
59
- @head.person_location.should be_nil
60
+ @head.person_fields.should be_nil
60
61
  end
61
62
  end
62
63
 
@@ -67,7 +68,7 @@ describe Mongoid::Alize do
67
68
  end
68
69
 
69
70
  def assert_person
70
- @person.head_size.should == @size
71
+ @person.head_fields.should == { "size" => @size }
71
72
  end
72
73
 
73
74
  it "should pull data from head on create" do
@@ -88,9 +89,9 @@ describe Mongoid::Alize do
88
89
  end
89
90
 
90
91
  it "should nillify head fields in person when head is destroyed" do
91
- @person.update_attributes!(:head_size => "1000 balloons")
92
+ @person.update_attributes!(:head_fields => { "size" => "1000 balloons"})
92
93
  @head.destroy
93
- @person.head_size.should be_nil
94
+ @person.head_fields.should be_nil
94
95
  end
95
96
  end
96
97
  end
@@ -103,7 +104,7 @@ describe Mongoid::Alize do
103
104
  end
104
105
 
105
106
  def assert_captor
106
- @head.captor_name.should == @name
107
+ @head.captor_fields.should == { "name" => @name, "location" => "Paris" }
107
108
  end
108
109
 
109
110
  it "should pull data from captor on create" do
@@ -124,9 +125,9 @@ describe Mongoid::Alize do
124
125
  end
125
126
 
126
127
  it "should nillify captor fields when person is destroyed" do
127
- @head.update_attributes!(:captor_name => "Old Gregg")
128
+ @head.update_attributes!(:captor => { "name" => "Old Gregg"})
128
129
  @person.destroy
129
- @head.captor_name.should be_nil
130
+ @head.captor_fields.should be_nil
130
131
  end
131
132
  end
132
133
 
@@ -216,15 +217,45 @@ describe Mongoid::Alize do
216
217
  end
217
218
 
218
219
  describe "without specifying fields" do
219
- before do
220
- Head.send(:alize, :person)
221
- @head.person = @person
220
+ describe "for non-polymorphic" do
221
+ before do
222
+ @head.person = @person
223
+ end
224
+
225
+ it "should denormalize all non-internal fields" do
226
+ Head.send(:alize, :person)
227
+ @head.save!
228
+ @head.person_fields.should == {
229
+ "name" => @name,
230
+ "created_at" => @person.created_at,
231
+ "seen_by_id" => nil,
232
+ "want_ids" => []
233
+ }
234
+ end
235
+
236
+ it "should denormalize all non-internal fields" do
237
+ Head.send(:alize, :person)
238
+ @person.save!
239
+ @head.person_fields.should == {
240
+ "name" => @name,
241
+ "created_at" => @person.created_at,
242
+ "seen_by_id" => nil,
243
+ "want_ids" => []
244
+ }
245
+ end
222
246
  end
223
247
 
224
- it "should denormalize all non-internal fields" do
225
- @head.save!
226
- @head.person_name.should == @name
227
- @head.person_created_at.to_i.should == @now.to_i
248
+ describe "for polymorphic" do
249
+ before do
250
+ @head.person = @person
251
+ end
252
+
253
+ it "should denormalize no default fields for a polymorphic child side" do
254
+ @head.nearest = @person
255
+ Head.send(:alize_from, :nearest)
256
+ @head.save!
257
+ @head.nearest_fields.should == {}
258
+ end
228
259
  end
229
260
  end
230
261
 
@@ -249,7 +280,7 @@ describe Mongoid::Alize do
249
280
 
250
281
  it "should be possible to define a method before alize and call the alize version within it" do
251
282
  @head.save!
252
- @head.person_name.should == "Overrider"
283
+ @head.person_fields["name"].should == "Overrider"
253
284
  end
254
285
  end
255
286
 
@@ -269,7 +300,7 @@ describe Mongoid::Alize do
269
300
 
270
301
  it "should be possible to define a method before alize and call the alize version within it" do
271
302
  @person.update_attributes!(:name => @name = "Bill")
272
- @head.person_name.should == "Overrider"
303
+ @head.person_fields["name"].should == "Overrider"
273
304
  end
274
305
  end
275
306
 
@@ -287,16 +318,204 @@ describe Mongoid::Alize do
287
318
  end
288
319
  end
289
320
 
290
- @head.person_name = "Misty"
321
+ @head.person_fields["name"] = "Misty"
291
322
  @head.save!
292
- @head.person_name.should == @name
323
+ @head.person_fields["name"] = @name
293
324
  end
294
325
 
295
326
  it "should allow using the force_denormalization attribute to force denormalization" do
296
- @head.person_name = "Misty"
327
+ @head.person_fields["name"] = "Misty"
297
328
  @head.force_denormalization = true
298
329
  @head.save!
299
- @head.person_name.should == @name
330
+ @head.person_fields["name"] = @name
331
+ end
332
+ end
333
+
334
+ describe "using a proc to define fields" do
335
+ before do
336
+ Head.send(:alize, :person, :fields => lambda { |inverse|
337
+ self.alize_fields(inverse) })
338
+ @head.person = @person
339
+ end
340
+
341
+ def assert_head
342
+ @head.person_fields.should == {
343
+ "name" => @name,
344
+ "location" => "Paris"
345
+ }
346
+ end
347
+
348
+ it "should work the same way as it does with fields specified" do
349
+ @head.save!
350
+ assert_head
351
+ end
352
+ end
353
+
354
+ describe "using a proc to define fields for a one-to-one polymorphic association from the belongs to side" do
355
+ before do
356
+ Head.send(:alize, :nearest, :fields => lambda { |inverse|
357
+ self.alize_fields(inverse) })
358
+ @head.nearest = @person
359
+ end
360
+
361
+ def assert_head
362
+ @head.nearest_fields.should == {
363
+ "name" => @name,
364
+ "location" => "Paris"
365
+ }
366
+ end
367
+
368
+ it "should work the same way as it does with fields specified" do
369
+ @head.save!
370
+ assert_head
371
+ end
372
+ end
373
+
374
+ describe "using a proc to define fields for a one-to-one polymorphic association from the has one side" do
375
+ before do
376
+ Person.send(:alize, :nearest_head, :fields => lambda { |inverse|
377
+ self.alize_fields(inverse) })
378
+ @person.nearest_head = @head
379
+ end
380
+
381
+ def assert_person
382
+ @person.nearest_head_fields.should == {
383
+ "size" => @size
384
+ }
385
+ end
386
+
387
+ it "should work the same way as it does with fields specified" do
388
+ @person.save!
389
+ assert_person
390
+ end
391
+ end
392
+
393
+ describe "using a proc to define fields for a has many polymorphic association from the :as side" do
394
+ before do
395
+ Head.send(:alize, :below_people, :fields => lambda { |inverse|
396
+ self.alize_fields(inverse) })
397
+ @head.below_people = [@person]
398
+ end
399
+
400
+ def assert_head
401
+ @head.below_people_fields.should == [{
402
+ "_id" => @person.id,
403
+ "name" => @name,
404
+ "location" => "Paris"
405
+ }]
406
+ end
407
+
408
+ it "should work the same way as it does with fields specified" do
409
+ @head.save!
410
+ assert_head
411
+ end
412
+ end
413
+
414
+ describe "using a proc to define fields for a has many polymorphic association from the belongs_to side" do
415
+ before do
416
+ Person.send(:alize, :above, :fields => lambda { |inverse|
417
+ self.alize_fields(inverse) })
418
+ @person.above = @head
419
+ end
420
+
421
+ def assert_person
422
+ @person.above_fields.should == {
423
+ "size" => @size,
424
+ }
425
+ end
426
+
427
+ it "should work the same way as it does with fields specified" do
428
+ @person.save!
429
+ assert_person
430
+ end
431
+ end
432
+
433
+ describe "the push on the child side of a one-to-one polymorphic" do
434
+ before do
435
+ fields = { :fields => lambda { |person| [:name, :location] } }
436
+ Head.send(:alize, :nearest, fields)
437
+ Person.send(:alize_to, :nearest_head, fields)
438
+ @head.nearest = @person
439
+ end
440
+
441
+ def assert_head
442
+ @head.nearest_fields.should == {
443
+ "name" => @name,
444
+ "location" => "Paris"
445
+ }
446
+ end
447
+
448
+ it "should push the new fields" do
449
+ @head.save!
450
+ assert_head
451
+ @person.update_attributes!(:name => @name = "George")
452
+ assert_head
453
+ end
454
+ end
455
+
456
+ describe "the push on the child side of a one-to-many polymorphic" do
457
+ before do
458
+ fields = { :fields => lambda { |head| [:size] } }
459
+ Person.send(:alize, :above, fields)
460
+ Head.send(:alize_to, :below_people, fields)
461
+ @person.above = @head
462
+ end
463
+
464
+ def assert_person
465
+ @person.above_fields.should == {
466
+ "size" => @size
467
+ }
468
+ end
469
+
470
+ it "should push the new fields" do
471
+ @person.save!
472
+ assert_person
473
+ @head.update_attributes!(:size => @size = 5)
474
+ assert_person
475
+ end
476
+ end
477
+
478
+ describe "the push on the parent side of a one-to-one polymorphic" do
479
+ before do
480
+ fields = { :fields => lambda { |inverse| [:size] } }
481
+ Person.send(:alize, :nearest_head, fields)
482
+ @person.nearest_head = @head
483
+ @person.save!
484
+ end
485
+
486
+ def assert_person
487
+ @person.nearest_head_fields.should == {
488
+ "size" => @size
489
+ }
490
+ end
491
+
492
+ it "should push the new fields" do
493
+ assert_person
494
+ @head.update_attributes!(:size => @size = 5)
495
+ assert_person
496
+ end
497
+ end
498
+
499
+ describe "the push on the parent side of a one-to-many polymorphic" do
500
+ before do
501
+ fields = { :fields => lambda { |inverse| [:name, :location] } }
502
+ Head.send(:alize, :below_people, fields)
503
+ @head.below_people = [@person]
504
+ @head.save!
505
+ end
506
+
507
+ def assert_head
508
+ @head.below_people_fields.should == [{
509
+ "_id" => @person.id,
510
+ "name" => @name,
511
+ "location" => "Paris"
512
+ }]
513
+ end
514
+
515
+ it "should push the new fields" do
516
+ assert_head
517
+ @person.update_attributes!(:name => @name = "George")
518
+ assert_head
300
519
  end
301
520
  end
302
521
  end