Commit 64154223 authored by Jens Segers's avatar Jens Segers

Embedded relations now return regular Eloquent collections

parent 236d7c50
......@@ -94,6 +94,8 @@ class User extends Eloquent {
}
```
Embedded relations now return an `Illuminate\Database\Eloquent\Collection` rather than a custom Collection class. If you were using one of the special methods that were available, convert them to Collection operations.
Configuration
-------------
......@@ -558,6 +560,8 @@ Supported relations are:
- hasMany
- belongsTo
- belongsToMany
- embedsOne
- embedsMany
Example:
......@@ -611,6 +615,8 @@ Other relations are not yet supported, but may be added in the future. Read more
If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation, but embeds the models inside the parent object.
**REMEMBER**: these relations return Eloquent collections, they don't return query builder objects!
```php
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
......
<?php namespace Jenssegers\Mongodb\Eloquent;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
class Collection extends EloquentCollection
{
/**
* Simulate a get clause on the collection.
*
* @param mixed $key
* @param mixed $default
* @return mixed
*/
public function get($key = null, $default = null)
{
if (is_null($key) and is_null($default)) {
return $this;
}
return parent::get($key, $default);
}
/**
* Simulate a basic where clause on the collection.
*
* @param string $key
* @param string $operator
* @param mixed $value
* @param string $boolean
* @return $this
*/
public function where($key, $operator = null, $value = null)
{
// Here we will make some assumptions about the operator. If only 2 values are
// passed to the method, we will assume that the operator is an equals sign
// and keep going.
if (func_num_args() == 2) {
list($value, $operator) = [$operator, '='];
}
return $this->filter(function ($item) use ($key, $operator, $value) {
$actual = $item->{$key};
switch ($operator) {
case '<>':
case '!=':
return $actual != $value;
break;
case '>':
return $actual > $value;
break;
case '<':
return $actual < $value;
break;
case '>=':
return $actual >= $value;
break;
case '<=':
return $actual <= $value;
break;
case 'between':
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;
break;
}
});
}
/**
* 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 $this
*/
public function orderBy($key, $direction = 'asc')
{
$descending = strtolower($direction) == 'desc';
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);
}
}
......@@ -10,7 +10,7 @@ class EmbedsMany extends EmbedsOneOrMany
/**
* Get the results of the relationship.
*
* @return \Jenssegers\Mongodb\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getResults()
{
......@@ -319,8 +319,7 @@ class EmbedsMany extends EmbedsOneOrMany
*/
public function __call($method, $parameters)
{
// Collection methods
if (method_exists('Jenssegers\Mongodb\Eloquent\Collection', $method)) {
if (method_exists('Illuminate\Database\Eloquent\Collection', $method)) {
return call_user_func_array([$this->getResults(), $method], $parameters);
}
......
<?php namespace Jenssegers\Mongodb\Relations;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection as BaseCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use Jenssegers\Mongodb\Eloquent\Collection;
abstract class EmbedsOneOrMany extends Relation
{
......@@ -101,7 +100,7 @@ abstract class EmbedsOneOrMany extends Relation
* @param string $relation
* @return array
*/
public function match(array $models, BaseCollection $results, $relation)
public function match(array $models, Collection $results, $relation)
{
foreach ($models as $model) {
$results = $model->$relation()->getResults();
......@@ -117,7 +116,7 @@ abstract class EmbedsOneOrMany extends Relation
/**
* Shorthand to get the results of the relationship.
*
* @return \Jenssegers\Mongodb\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection
*/
public function get()
{
......
......@@ -424,70 +424,19 @@ class EmbeddedRelationsTest extends TestCase
$this->assertEquals(['Paris', 'Bruges', 'Brussels', 'Ghent'], $user->addresses()->lists('city')->all());
$this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()->sortBy('city')->lists('city')->all());
$this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()->orderBy('city')->lists('city')->all());
$this->assertEquals(['Paris', 'Ghent', 'Brussels', 'Bruges'], $user->addresses()->orderBy('city', 'desc')->lists('city')->all());
$this->assertEquals([], $user->addresses()->where('city', 'New York')->lists('city')->all());
$this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()->where('country', 'Belgium')->lists('city')->all());
$this->assertEquals(['Ghent', 'Brussels', 'Bruges'], $user->addresses()->where('country', 'Belgium')->orderBy('city', 'desc')->lists('city')->all());
$this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()->where('country', 'Belgium')->sortBy('city')->lists('city')->all());
$results = $user->addresses->get(0);
$results = $user->addresses->first();
$this->assertInstanceOf('Address', $results);
$results = $user->addresses()->where('country', 'Belgium')->get();
$this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Collection', $results);
$this->assertEquals(3, $results->count());
$results = $user->addresses()->where('country', '!=', 'Belgium')->get();
$this->assertEquals(1, $results->count());
$results = $user->addresses()->where('visited', '>', 4)->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->where('visited', '<', 7)->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->where('visited', '<=', 7)->get();
$this->assertEquals(3, $results->count());
$results = $user->addresses()->where('visited', '>=', 7)->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->where('visited', 'between', [4, 7])->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereBetween('visited', [4, 7])->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereNotBetween('visited', [4, 7])->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereIn('visited', [7, 13])->get();
$this->assertEquals(2, $results->count());
$results = $user->addresses()->whereNotIn('visited', [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();
$results = $user->addresses()->where('country', 'Belgium');
$this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $results);
$this->assertEquals(3, $results->count());
$results = $user->addresses()->skip(1)->get();
$this->assertEquals(3, $results->count());
$results = $user->addresses()->limit(2)->get();
$results = $user->addresses()->whereIn('visited', [7, 13]);
$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()
......
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