Commit 12abfb36 authored by Jens Segers's avatar Jens Segers

Expanding query operations on collections

parent 274a31da
......@@ -486,10 +486,17 @@ Like other relations, embedsMany assumes the local key of the relationship based
return $this->embedsMany('Book', 'local_key');
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:
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:
- where($key, $operator, $value)
- whereIn($key, $values) and whereNotIn($key, $values)
- whereBetween($key, $values) and whereNotBetween($key, $values)
- whereNull($key) and whereNotNull($key)
- orderBy($key, $direction)
- oldest() and latest()
- limit($value)
- offset($value)
- skip($value)
This allows you to execute simple queries on the collection results:
......
......@@ -71,6 +71,18 @@ class Collection extends EloquentCollection {
return $actual >= $value[0] and $actual <= $value[1];
break;
case 'not between':
return $actual < $value[0] or $actual > $value[1];
break;
case 'in':
return in_array($actual, $value);
break;
case 'not in':
return ! in_array($actual, $value);
break;
case '=':
default:
return $actual == $value;
......@@ -79,12 +91,95 @@ class Collection extends EloquentCollection {
});
}
/**
* Add a where between statement to the query.
*
* @param string $column
* @param array $values
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereBetween($column, array $values, $boolean = 'and', $not = false)
{
$type = $not ? 'not between' : 'between';
return $this->where($column, $type, $values);
}
/**
* Add a where not between statement to the query.
*
* @param string $column
* @param array $values
* @param string $boolean
* @return $this
*/
public function whereNotBetween($column, array $values, $boolean = 'and')
{
return $this->whereBetween($column, $values, $boolean, true);
}
/**
* Add a "where in" clause to the query.
*
* @param string $column
* @param mixed $values
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereIn($column, $values, $boolean = 'and', $not = false)
{
$type = $not ? 'not in' : 'in';
return $this->where($column, $type, $values);
}
/**
* Add a "where not in" clause to the query.
*
* @param string $column
* @param mixed $values
* @param string $boolean
* @return $this
*/
public function whereNotIn($column, $values, $boolean = 'and')
{
return $this->whereIn($column, $values, $boolean, true);
}
/**
* Add a "where null" clause to the query.
*
* @param string $column
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereNull($column, $boolean = 'and', $not = false)
{
return $this->where($column, '=', null);
}
/**
* Add a "where not null" clause to the query.
*
* @param string $column
* @param string $boolean
* @return $this
*/
public function whereNotNull($column, $boolean = 'and')
{
return $this->where($column, '!=', null);
}
/**
* Simulate order by clause on the collection.
*
* @param string $key
* @param string $direction
* @return Illuminate\Database\Eloquent\Collection
* @return $this
*/
public function orderBy($key, $direction = 'asc')
{
......@@ -93,4 +188,61 @@ class Collection extends EloquentCollection {
return $this->sortBy($key, SORT_REGULAR, $descending);
}
/**
* Add an "order by" clause for a timestamp to the query.
*
* @param string $column
* @return $this
*/
public function latest($column = 'created_at')
{
return $this->orderBy($column, 'desc');
}
/**
* Add an "order by" clause for a timestamp to the query.
*
* @param string $column
* @return $this
*/
public function oldest($column = 'created_at')
{
return $this->orderBy($column, 'asc');
}
/**
* Set the "offset" value of the query.
*
* @param int $value
* @return $this
*/
public function offset($value)
{
$offset = max(0, $value);
return $this->slice($offset);
}
/**
* Alias to set the "offset" value of the query.
*
* @param int $value
* @return $this
*/
public function skip($value)
{
return $this->offset($value);
}
/**
* Set the "limit" value of the query.
*
* @param int $value
* @return $this
*/
public function limit($value)
{
return $this->take($value);
}
}
......@@ -416,10 +416,10 @@ class EmbeddedRelationsTest extends TestCase {
public function testEmbedsManyCollectionMethods()
{
$user = User::create(array('name' => 'John Doe'));
$user->addresses()->save(new Address(array('city' => 'Paris', 'country' => 'France', 'visited' => 4)));
$user->addresses()->save(new Address(array('city' => 'Bruges', 'country' => 'Belgium', 'visited' => 7)));
$user->addresses()->save(new Address(array('city' => 'Brussels', 'country' => 'Belgium', 'visited' => 2)));
$user->addresses()->save(new Address(array('city' => 'Ghent', 'country' => 'Belgium', 'visited' => 13)));
$user->addresses()->save(new Address(array('city' => 'Paris', 'country' => 'France', 'visited' => 4, 'created_at' => new DateTime('3 days ago'))));
$user->addresses()->save(new Address(array('city' => 'Bruges', 'country' => 'Belgium', 'visited' => 7, 'created_at' => new DateTime('5 days ago'))));
$user->addresses()->save(new Address(array('city' => 'Brussels', 'country' => 'Belgium', 'visited' => 2, 'created_at' => new DateTime('4 days ago'))));
$user->addresses()->save(new Address(array('city' => 'Ghent', 'country' => 'Belgium', 'visited' => 13, 'created_at' => new DateTime('2 days ago'))));
$this->assertEquals(array('Paris', 'Bruges', 'Brussels', 'Ghent'), $user->addresses()->lists('city'));
$this->assertEquals(array('Bruges', 'Brussels', 'Ghent', 'Paris'), $user->addresses()->sortBy('city')->lists('city'));
......@@ -430,6 +430,9 @@ class EmbeddedRelationsTest extends TestCase {
$this->assertEquals(array('Bruges', 'Brussels', 'Ghent'), $user->addresses()->where('country', 'Belgium')->lists('city'));
$this->assertEquals(array('Ghent', 'Brussels', 'Bruges'), $user->addresses()->where('country', 'Belgium')->orderBy('city', 'desc')->lists('city'));
$results = $user->addresses->get(0);
$this->assertInstanceOf('Address', $results);
$results = $user->addresses()->where('country', 'Belgium')->get();
$this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Collection', $results);
$this->assertEquals(3, $results->count());
......@@ -451,6 +454,39 @@ class EmbeddedRelationsTest extends TestCase {
$results = $user->addresses()->where('visited', 'between', array(4, 7))->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereBetween('visited', array(4, 7))->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereNotBetween('visited', array(4, 7))->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereIn('visited', array(7, 13))->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereNotIn('visited', array(7))->get();
$this->assertEquals(3, $results->count());
$results = $user->addresses()->whereNull('something')->get();
$this->assertEquals(4, $results->count());
$results = $user->addresses()->whereNotNull('visited')->get();
$this->assertEquals(4, $results->count());
$results = $user->addresses()->offset(1)->get();
$this->assertEquals(3, $results->count());
$results = $user->addresses()->skip(1)->get();
$this->assertEquals(3, $results->count());
$results = $user->addresses()->limit(2)->get();
$this->assertEquals(2, $results->count());
$result = $user->addresses()->latest()->first();
$this->assertEquals('Ghent', $result->city);
$result = $user->addresses()->oldest()->first();
$this->assertEquals('Bruges', $result->city);
}
public function testEmbedsOne()
......
......@@ -400,6 +400,9 @@ class ModelTest extends TestCase {
$user = User::create(array('name' => 'Jane Doe', 'entry' => array('date' => '2005-08-08')));
$this->assertInstanceOf('Carbon\Carbon', $user->getAttribute('entry.date'));
$user->setAttribute('entry.date', new DateTime);
$this->assertInstanceOf('Carbon\Carbon', $user->getAttribute('entry.date'));
}
public function testIdAttribute()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment