Skip to content

Commit 12abfb3

Browse files
committed
Expanding query operations on collections
1 parent 274a31d commit 12abfb3

File tree

4 files changed

+204
-6
lines changed

4 files changed

+204
-6
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,17 @@ Like other relations, embedsMany assumes the local key of the relationship based
486486

487487
return $this->embedsMany('Book', 'local_key');
488488

489-
Embedded relations will return a Collection of embedded items instead of a query builder. To allow a more query-like behavior, embedded relations will return a modified version of the Collection class with support for the following operations:
489+
Embedded relations will return a Collection of embedded items instead of a query builder. To allow a more query-like behavior, embedded relations will return a modified version of the Collection class with support for the following **additional** operations:
490490

491491
- where($key, $operator, $value)
492+
- whereIn($key, $values) and whereNotIn($key, $values)
493+
- whereBetween($key, $values) and whereNotBetween($key, $values)
494+
- whereNull($key) and whereNotNull($key)
492495
- orderBy($key, $direction)
496+
- oldest() and latest()
497+
- limit($value)
498+
- offset($value)
499+
- skip($value)
493500

494501
This allows you to execute simple queries on the collection results:
495502

src/Jenssegers/Mongodb/Eloquent/Collection.php

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ public function where($key, $operator = null, $value = null)
7171
return $actual >= $value[0] and $actual <= $value[1];
7272
break;
7373

74+
case 'not between':
75+
return $actual < $value[0] or $actual > $value[1];
76+
break;
77+
78+
case 'in':
79+
return in_array($actual, $value);
80+
break;
81+
82+
case 'not in':
83+
return ! in_array($actual, $value);
84+
break;
85+
7486
case '=':
7587
default:
7688
return $actual == $value;
@@ -79,12 +91,95 @@ public function where($key, $operator = null, $value = null)
7991
});
8092
}
8193

94+
/**
95+
* Add a where between statement to the query.
96+
*
97+
* @param string $column
98+
* @param array $values
99+
* @param string $boolean
100+
* @param bool $not
101+
* @return $this
102+
*/
103+
public function whereBetween($column, array $values, $boolean = 'and', $not = false)
104+
{
105+
$type = $not ? 'not between' : 'between';
106+
107+
return $this->where($column, $type, $values);
108+
}
109+
110+
/**
111+
* Add a where not between statement to the query.
112+
*
113+
* @param string $column
114+
* @param array $values
115+
* @param string $boolean
116+
* @return $this
117+
*/
118+
public function whereNotBetween($column, array $values, $boolean = 'and')
119+
{
120+
return $this->whereBetween($column, $values, $boolean, true);
121+
}
122+
123+
/**
124+
* Add a "where in" clause to the query.
125+
*
126+
* @param string $column
127+
* @param mixed $values
128+
* @param string $boolean
129+
* @param bool $not
130+
* @return $this
131+
*/
132+
public function whereIn($column, $values, $boolean = 'and', $not = false)
133+
{
134+
$type = $not ? 'not in' : 'in';
135+
136+
return $this->where($column, $type, $values);
137+
}
138+
139+
/**
140+
* Add a "where not in" clause to the query.
141+
*
142+
* @param string $column
143+
* @param mixed $values
144+
* @param string $boolean
145+
* @return $this
146+
*/
147+
public function whereNotIn($column, $values, $boolean = 'and')
148+
{
149+
return $this->whereIn($column, $values, $boolean, true);
150+
}
151+
152+
/**
153+
* Add a "where null" clause to the query.
154+
*
155+
* @param string $column
156+
* @param string $boolean
157+
* @param bool $not
158+
* @return $this
159+
*/
160+
public function whereNull($column, $boolean = 'and', $not = false)
161+
{
162+
return $this->where($column, '=', null);
163+
}
164+
165+
/**
166+
* Add a "where not null" clause to the query.
167+
*
168+
* @param string $column
169+
* @param string $boolean
170+
* @return $this
171+
*/
172+
public function whereNotNull($column, $boolean = 'and')
173+
{
174+
return $this->where($column, '!=', null);
175+
}
176+
82177
/**
83178
* Simulate order by clause on the collection.
84179
*
85180
* @param string $key
86181
* @param string $direction
87-
* @return Illuminate\Database\Eloquent\Collection
182+
* @return $this
88183
*/
89184
public function orderBy($key, $direction = 'asc')
90185
{
@@ -93,4 +188,61 @@ public function orderBy($key, $direction = 'asc')
93188
return $this->sortBy($key, SORT_REGULAR, $descending);
94189
}
95190

191+
/**
192+
* Add an "order by" clause for a timestamp to the query.
193+
*
194+
* @param string $column
195+
* @return $this
196+
*/
197+
public function latest($column = 'created_at')
198+
{
199+
return $this->orderBy($column, 'desc');
200+
}
201+
202+
/**
203+
* Add an "order by" clause for a timestamp to the query.
204+
*
205+
* @param string $column
206+
* @return $this
207+
*/
208+
public function oldest($column = 'created_at')
209+
{
210+
return $this->orderBy($column, 'asc');
211+
}
212+
213+
/**
214+
* Set the "offset" value of the query.
215+
*
216+
* @param int $value
217+
* @return $this
218+
*/
219+
public function offset($value)
220+
{
221+
$offset = max(0, $value);
222+
223+
return $this->slice($offset);
224+
}
225+
226+
/**
227+
* Alias to set the "offset" value of the query.
228+
*
229+
* @param int $value
230+
* @return $this
231+
*/
232+
public function skip($value)
233+
{
234+
return $this->offset($value);
235+
}
236+
237+
/**
238+
* Set the "limit" value of the query.
239+
*
240+
* @param int $value
241+
* @return $this
242+
*/
243+
public function limit($value)
244+
{
245+
return $this->take($value);
246+
}
247+
96248
}

tests/EmbeddedRelationsTest.php

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,10 @@ public function testEmbedsManyDeleteAll()
416416
public function testEmbedsManyCollectionMethods()
417417
{
418418
$user = User::create(array('name' => 'John Doe'));
419-
$user->addresses()->save(new Address(array('city' => 'Paris', 'country' => 'France', 'visited' => 4)));
420-
$user->addresses()->save(new Address(array('city' => 'Bruges', 'country' => 'Belgium', 'visited' => 7)));
421-
$user->addresses()->save(new Address(array('city' => 'Brussels', 'country' => 'Belgium', 'visited' => 2)));
422-
$user->addresses()->save(new Address(array('city' => 'Ghent', 'country' => 'Belgium', 'visited' => 13)));
419+
$user->addresses()->save(new Address(array('city' => 'Paris', 'country' => 'France', 'visited' => 4, 'created_at' => new DateTime('3 days ago'))));
420+
$user->addresses()->save(new Address(array('city' => 'Bruges', 'country' => 'Belgium', 'visited' => 7, 'created_at' => new DateTime('5 days ago'))));
421+
$user->addresses()->save(new Address(array('city' => 'Brussels', 'country' => 'Belgium', 'visited' => 2, 'created_at' => new DateTime('4 days ago'))));
422+
$user->addresses()->save(new Address(array('city' => 'Ghent', 'country' => 'Belgium', 'visited' => 13, 'created_at' => new DateTime('2 days ago'))));
423423

424424
$this->assertEquals(array('Paris', 'Bruges', 'Brussels', 'Ghent'), $user->addresses()->lists('city'));
425425
$this->assertEquals(array('Bruges', 'Brussels', 'Ghent', 'Paris'), $user->addresses()->sortBy('city')->lists('city'));
@@ -430,6 +430,9 @@ public function testEmbedsManyCollectionMethods()
430430
$this->assertEquals(array('Bruges', 'Brussels', 'Ghent'), $user->addresses()->where('country', 'Belgium')->lists('city'));
431431
$this->assertEquals(array('Ghent', 'Brussels', 'Bruges'), $user->addresses()->where('country', 'Belgium')->orderBy('city', 'desc')->lists('city'));
432432

433+
$results = $user->addresses->get(0);
434+
$this->assertInstanceOf('Address', $results);
435+
433436
$results = $user->addresses()->where('country', 'Belgium')->get();
434437
$this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Collection', $results);
435438
$this->assertEquals(3, $results->count());
@@ -451,6 +454,39 @@ public function testEmbedsManyCollectionMethods()
451454

452455
$results = $user->addresses()->where('visited', 'between', array(4, 7))->get();
453456
$this->assertEquals(2, $results->count());
457+
458+
$results = $user->addresses()->whereBetween('visited', array(4, 7))->get();
459+
$this->assertEquals(2, $results->count());
460+
461+
$results = $user->addresses()->whereNotBetween('visited', array(4, 7))->get();
462+
$this->assertEquals(2, $results->count());
463+
464+
$results = $user->addresses()->whereIn('visited', array(7, 13))->get();
465+
$this->assertEquals(2, $results->count());
466+
467+
$results = $user->addresses()->whereNotIn('visited', array(7))->get();
468+
$this->assertEquals(3, $results->count());
469+
470+
$results = $user->addresses()->whereNull('something')->get();
471+
$this->assertEquals(4, $results->count());
472+
473+
$results = $user->addresses()->whereNotNull('visited')->get();
474+
$this->assertEquals(4, $results->count());
475+
476+
$results = $user->addresses()->offset(1)->get();
477+
$this->assertEquals(3, $results->count());
478+
479+
$results = $user->addresses()->skip(1)->get();
480+
$this->assertEquals(3, $results->count());
481+
482+
$results = $user->addresses()->limit(2)->get();
483+
$this->assertEquals(2, $results->count());
484+
485+
$result = $user->addresses()->latest()->first();
486+
$this->assertEquals('Ghent', $result->city);
487+
488+
$result = $user->addresses()->oldest()->first();
489+
$this->assertEquals('Bruges', $result->city);
454490
}
455491

456492
public function testEmbedsOne()

tests/ModelTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ public function testDates()
400400

401401
$user = User::create(array('name' => 'Jane Doe', 'entry' => array('date' => '2005-08-08')));
402402
$this->assertInstanceOf('Carbon\Carbon', $user->getAttribute('entry.date'));
403+
404+
$user->setAttribute('entry.date', new DateTime);
405+
$this->assertInstanceOf('Carbon\Carbon', $user->getAttribute('entry.date'));
403406
}
404407

405408
public function testIdAttribute()

0 commit comments

Comments
 (0)