Skip to content

Commit 8e57b37

Browse files
committed
Syncing
1 parent 4cabe86 commit 8e57b37

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

src/Jenssegers/Mongodb/Relations/BelongsTo.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Jenssegers\Mongodb\Relations;
44

55
use Illuminate\Database\Eloquent\Builder;
6+
use Illuminate\Database\Eloquent\Collection;
67
use Illuminate\Database\Eloquent\Model as EloquentModel;
78

89
class BelongsTo extends \Illuminate\Database\Eloquent\Relations\BelongsTo
@@ -26,7 +27,9 @@ public function addConstraints()
2627
// For belongs to relationships, which are essentially the inverse of has one
2728
// or has many relationships, we need to actually query on the primary key
2829
// of the related models matching on the foreign key that's on a parent.
29-
$this->query->where($this->getOwnerKey(), '=', $this->parent->{$this->foreignKey});
30+
$this->query
31+
->where($this->getOwnerKey(), '=', $this->parent->{$this->foreignKey})
32+
->orWhere($this->getOwnerKey().'._id', '=', $this->parent->{$this->foreignKey});
3033
}
3134
}
3235

@@ -72,4 +75,34 @@ protected function whereInMethod(EloquentModel $model, $key)
7275
{
7376
return 'whereIn';
7477
}
78+
79+
/**
80+
* @inheritDoc
81+
*/
82+
public function match(array $models, Collection $results, $relation)
83+
{
84+
$foreign = $this->foreignKey;
85+
86+
$owner = $this->ownerKey;
87+
88+
// First we will get to build a dictionary of the child models by their primary
89+
// key of the relationship, then we can easily match the children back onto
90+
// the parents using that dictionary and the primary key of the children.
91+
$dictionary = [];
92+
93+
foreach ($results as $result) {
94+
$dictionary[$result->getAttribute($owner)] = $result;
95+
}
96+
97+
// Once we have the dictionary constructed, we can loop through all the parents
98+
// and match back onto their children using these keys of the dictionary and
99+
// the primary key of the children to map them onto the correct instances.
100+
foreach ($models as $model) {
101+
if (isset($dictionary[(string)$model->{$foreign}])) {
102+
$model->setRelation($relation, $dictionary[(string)$model->{$foreign}]);
103+
}
104+
}
105+
106+
return $models;
107+
}
75108
}

src/Jenssegers/Mongodb/Relations/BelongsToMany.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ public function sync($ids, $detaching = true)
141141
if ($current instanceof Collection) {
142142
$current = $ids->modelKeys();
143143
} elseif (is_array($current)) {
144+
144145
foreach ($current as $key => $value) {
145-
if ($value['_id']) {
146+
if (is_array($value) && $value['_id']) {
146147
$current[$key] = $value['_id'];
147148
}
148149
}
@@ -201,18 +202,20 @@ public function attach($id, array $attributes = [], $touch = true)
201202
$id = $model->getKey();
202203

203204
// Attach the new parent id to the related model.
204-
$model->push($this->foreignPivotKey, array_merge($attributes, ['_id' => $this->parent->getKey()]), true);
205+
$model->push($this->foreignPivotKey, [array_merge($attributes, ['_id' => $this->parent->getKey()])], true);
205206
} else {
206207
if ($id instanceof Collection) {
207208
$id = $id->modelKeys();
208209
}
209210

210211
$query = $this->newRelatedQuery();
211212

212-
$query->whereIn($this->related->getKeyName(), (array) $id);
213+
$query
214+
->whereIn($this->related->getKeyName(), (array)$id)
215+
->orWhereIn($this->related->getKeyName().'._id', (array)$id);
213216

214217
// Attach the new parent id to the related model.
215-
$query->push($this->foreignPivotKey, array_merge($attributes, ['_id' => $this->parent->getKey()]), true);
218+
$query->push($this->foreignPivotKey, [array_merge($attributes, ['_id' => $this->parent->getKey()])], true);
216219
}
217220

218221
//Pivot Collection
@@ -246,14 +249,19 @@ public function detach($ids = [], $touch = true)
246249
$ids = (array) $ids;
247250

248251
// Detach all ids from the parent model.
249-
$this->parent->pull($this->getRelatedKey(), ['_id'=>$ids]);
252+
// Legacy Support
253+
$this->parent->pull($this->getRelatedKey(), $ids);
254+
$this->parent->pull($this->getRelatedKey(), ['_id'=>['$in'=>$ids]]);
250255

251256
// Prepare the query to select all related objects.
252257
if (count($ids) > 0) {
253-
$query->whereIn($this->related->getKeyName(), $ids);
258+
$query
259+
->whereIn($this->related->getKeyName(), $ids)
260+
->orWhereIn($this->related->getKeyName().'._id', $ids);
254261
}
255262

256263
// Remove the relation to the parent.
264+
$query->pull($this->foreignPivotKey, $this->parent->getKey());
257265
$query->pull($this->foreignPivotKey, ['_id'=>$this->parent->getKey()]);
258266

259267
if ($touch) {

src/Jenssegers/Mongodb/Relations/HasMany.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
namespace Jenssegers\Mongodb\Relations;
44

55
use Illuminate\Database\Eloquent\Builder;
6-
use Illuminate\Database\Eloquent\Relations\HasMany as EloquentHasMany;
76
use Illuminate\Database\Eloquent\Model as EloquentModel;
7+
use Illuminate\Database\Eloquent\Relations\HasMany as EloquentHasMany;
88

99
class HasMany extends EloquentHasMany
1010
{
@@ -76,7 +76,9 @@ public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*
7676

7777
$key = $this->wrap($this->getQualifiedParentKeyName());
7878

79-
return $query->where($this->getHasCompareKey(), 'exists', true);
79+
return $query
80+
->where($this->getHasCompareKey(), 'exists', true)
81+
->orWhere($this->getHasCompareKey().'._id', 'exists', true);
8082
}
8183

8284
/**

tests/RelationsTest.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public function testBelongsToMany()
224224

225225
public function testBelongsToManyAttachesExistingModels()
226226
{
227-
$user = User::create(['name' => 'John Doe', 'client_ids' => ['1234523']]);
227+
$user = User::create(['name' => 'John Doe', 'client_ids' => [['_id'=>'1234523']]]);
228228

229229
$clients = [
230230
Client::create(['name' => 'Pork Pies Ltd.'])->_id,
@@ -239,7 +239,8 @@ public function testBelongsToManyAttachesExistingModels()
239239
// Sync multiple records
240240
$user->clients()->sync($clients);
241241

242-
$user = User::with('clients')->find($user->_id);
242+
// $user = User::with('clients')->find($user->_id);
243+
$user = User::find($user->_id);
243244

244245
// Assert non attached ID's are detached succesfully
245246
$this->assertNotContains('1234523', $user->client_ids);
@@ -543,20 +544,20 @@ public function testDoubleSaveManyToMany()
543544
$user->save();
544545

545546
$this->assertEquals(1, $user->clients()->count());
546-
$this->assertEquals([$user->_id], $client->user_ids);
547-
$this->assertEquals([$client->_id], $user->client_ids);
547+
$this->assertEquals([['_id' =>$user->_id]], $client->user_ids);
548+
$this->assertEquals([['_id' => $client->_id]], $user->client_ids);
548549

549550
$user = User::where('name', 'John Doe')->first();
550551
$client = Client::where('name', 'Admins')->first();
551552
$this->assertEquals(1, $user->clients()->count());
552-
$this->assertEquals([$user->_id], $client->user_ids);
553-
$this->assertEquals([$client->_id], $user->client_ids);
553+
$this->assertEquals([['_id' =>$user->_id]], $client->user_ids);
554+
$this->assertEquals([['_id' => $client->_id]], $user->client_ids);
554555

555556
$user->clients()->save($client);
556557
$user->clients()->save($client);
557558
$user->save();
558559
$this->assertEquals(1, $user->clients()->count());
559-
$this->assertEquals([$user->_id], $client->user_ids);
560-
$this->assertEquals([$client->_id], $user->client_ids);
560+
$this->assertEquals([['_id' =>$user->_id]], $client->user_ids);
561+
$this->assertEquals([['_id' => $client->_id]], $user->client_ids);
561562
}
562563
}

0 commit comments

Comments
 (0)