Skip to content

Commit 9d54af6

Browse files
author
yann ARMAND
committed
[back_assignments] add reverse_association on collections
1 parent 1fc6cf7 commit 9d54af6

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

lib/couchrest/model/associations.rb

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -247,49 +247,37 @@ def initialize(array, property, parent)
247247
end
248248

249249
def << obj
250-
check_obj(obj)
251-
casted_by[casted_by_property.to_s] << obj.id
252-
obj.set_back_association(casted_by, casted_by.class.name)
253-
casted_by.register_dirty_association(obj)
250+
add_to_collection_with(:<<, obj)
254251
super(obj)
255252
end
256253

257254
def push(obj)
258-
check_obj(obj)
259-
casted_by[casted_by_property.to_s].push obj.id
260-
obj.set_back_association(casted_by, casted_by.class.name)
261-
casted_by.register_dirty_association(obj)
255+
add_to_collection_with(:push, obj)
262256
super(obj)
263257
end
264258

265259
def unshift(obj)
266-
check_obj(obj)
267-
casted_by[casted_by_property.to_s].unshift obj.id
268-
obj.set_back_association(casted_by, casted_by.class.name)
269-
casted_by.register_dirty_association(obj)
260+
add_to_collection_with(:unshift, obj)
270261
super(obj)
271262
end
272263

273264
def []= index, obj
274-
check_obj(obj)
275-
casted_by[casted_by_property.to_s][index] = obj.id
276-
obj.set_back_association(casted_by, casted_by.class.name)
277-
casted_by.register_dirty_association(obj)
265+
add_to_collection_with(:[]=, obj, index)
278266
super(index, obj)
279267
end
280268

281269
def pop
282270
obj = casted_by.send(casted_by_property.options[:proxy_name]).last
283271
casted_by[casted_by_property.to_s].pop
284-
obj.set_back_association(nil, casted_by.class.name)
272+
obj.set_back_association(nil, casted_by.class.name, casted_by_property.options[:reverse_association])
285273
casted_by.register_dirty_association(obj)
286274
super
287275
end
288276

289277
def shift
290278
obj = casted_by.send(casted_by_property.options[:proxy_name]).first
291279
casted_by[casted_by_property.to_s].shift
292-
obj.set_back_association(nil, casted_by.class.name)
280+
obj.set_back_association(nil, casted_by.class.name, casted_by_property.options[:reverse_association])
293281
casted_by.register_dirty_association(obj)
294282
super
295283
end
@@ -300,6 +288,15 @@ def check_obj(obj)
300288
raise "Object cannot be added to #{casted_by.class.to_s}##{casted_by_property.to_s} collection unless saved" if obj.new?
301289
end
302290

291+
def add_to_collection_with(method, obj, index=nil)
292+
check_obj(obj)
293+
args = [ obj.id ]
294+
args = args.insert(0, index) if index
295+
casted_by[casted_by_property.to_s].send(method, *args)
296+
obj.set_back_association(casted_by, casted_by.class.name, casted_by_property.options[:reverse_association])
297+
casted_by.register_dirty_association(obj)
298+
end
299+
303300
# Override CastedArray instantiation_and_cast method for a simpler
304301
# version that will not try to cast the model.
305302
def instantiate_and_cast(obj, change = true)

spec/fixtures/models/parent.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ class Parent < CouchRest::Model::Base
77
belongs_to :lives_with, :class_name => :parent, :reverse_association => :lives_with
88

99
collection_of :children, :class_name => 'Kid'
10+
collection_of :pets , :reverse_association => :owner
1011
end

spec/unit/assocations_dual_spec.rb

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
let(:father) { Parent.create(name: 'Bob')}
77
let(:can_fly){ SuperPower.create(description: 'Can fly when there is no cloud')}
8-
let(:mummy) { Parent.create( name: 'Claire')}
9-
let(:kid) { Kid.create( name: 'Vladimir')}
8+
let(:mummy) { Parent.create(name: 'Claire')}
9+
let(:kid) { Kid.create( name: 'Vladimir')}
10+
let(:dog) { Pet.create( name: 'Valdo' )}
1011

1112
describe 'of type belongs_to' do
1213
context 'with the other side also belongs_to (1-1)' do
@@ -72,6 +73,12 @@
7273
father.children << kid
7374
kid.dad.should eq(father)
7475
end
76+
context 'when reverse_association is specified' do
77+
it 'should populate the belongs_to property' do
78+
father.pets << dog
79+
dog.owner.should eq(father)
80+
end
81+
end
7582
describe 'when object is saved' do
7683
it 'should also save other side' do
7784
father.children << kid
@@ -86,6 +93,12 @@
8693
father.children.push kid
8794
kid.dad.should eq(father)
8895
end
96+
context 'when reverse_association is specified' do
97+
it 'should populate the belongs_to property' do
98+
father.pets.push dog
99+
dog.owner.should eq(father)
100+
end
101+
end
89102
describe 'when object is saved' do
90103
it 'should also save other side' do
91104
father.children.push kid
@@ -100,6 +113,10 @@
100113
father.children.unshift kid
101114
kid.dad.should eq(father)
102115
end
116+
it 'should populate the belongs_to property' do
117+
father.pets.unshift dog
118+
dog.owner.should eq(father)
119+
end
103120
describe 'when object is saved' do
104121
it 'should also save other side' do
105122
father.children.unshift kid
@@ -114,6 +131,10 @@
114131
father.children[3]= kid
115132
kid.dad.should eq(father)
116133
end
134+
it 'should populate the belongs_to property' do
135+
father.pets[3] = dog
136+
dog.owner.should eq(father)
137+
end
117138
describe 'when object is saved' do
118139
it 'should also save other side' do
119140
father.children[4] = kid
@@ -129,6 +150,13 @@
129150
father.children.pop
130151
kid.dad.should be_nil
131152
end
153+
context 'specifying reverse association' do
154+
it 'should set nil the belongs_to property' do
155+
father.pets.push dog
156+
father.pets.pop
157+
dog.owner.should be_nil
158+
end
159+
end
132160
describe 'when object is saved' do
133161
it 'should also save other side' do
134162
father.children.push kid
@@ -146,6 +174,13 @@
146174
father.children.shift
147175
kid.dad.should be_nil
148176
end
177+
context 'specifying reverse association' do
178+
it 'should set nil the belongs_to property' do
179+
father.pets.push dog
180+
father.pets.shift
181+
dog.owner.should be_nil
182+
end
183+
end
149184
describe 'when object is saved' do
150185
it 'should also save other side' do
151186
father.children.push kid

0 commit comments

Comments
 (0)