Skip to content

Commit e69a072

Browse files
committed
Merge branch 'master' into develop
2 parents ded65cd + 128eb7b commit e69a072

File tree

13 files changed

+793
-12
lines changed

13 files changed

+793
-12
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ branches:
44
only:
55
- master
66
- develop
7+
- 4.0
78

89
php:
910
- 5.3

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,49 @@ The belongsToMany relation will not use a pivot "table", but will push id's to a
359359

360360
Other relations are not yet supported, but may be added in the future. Read more about these relations on http://four.laravel.com/docs/eloquent#relationships
361361

362+
### EmbedsMany Relations
363+
364+
If you want to embed documents, rather than referencing them, you can use the `embedsMany` relation:
365+
366+
use Jenssegers\Mongodb\Model as Eloquent;
367+
368+
class User extends Eloquent {
369+
370+
public function books()
371+
{
372+
return $this->embedsMany('Book');
373+
}
374+
375+
}
376+
377+
Now we can access the user's books through the dynamic property:
378+
379+
$books = User::first()->books;
380+
381+
When using embedded documents, there will also be an inverse relation available:
382+
383+
$user = $book->user;
384+
385+
Inserting and updating embedded documents works just like the `belongsTo` relation:
386+
387+
$book = new Book(array('title' => 'A Game of Thrones'));
388+
389+
$user = User::first();
390+
391+
$book = $user->books()->save($book);
392+
393+
You can remove an embedded document by using the `destroy()` method:
394+
395+
$book = $user->books()->first();
396+
397+
$user->books()->destroy($book->_id);
398+
// or
399+
$user->books()->destroy($book);
400+
401+
Again, you may override the conventional local key by passing a second argument to the embedsMany method:
402+
403+
return $this->embedsMany('Book', 'local_key');
404+
362405
### MySQL Relations
363406

364407
If you're using a hybrid MongoDB and SQL setup, you're in luck! The model will automatically return a MongoDB- or SQL-relation based on the type of the related model. Of course, if you want this functionality to work both ways, your SQL-models will need to extend `Jenssegers\Eloquent\Model`. Note that this functionality only works for hasOne, hasMany and belongsTo relations.

phpunit.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
</testsuite>
3535
<testsuite name="relations">
3636
<directory>tests/RelationsTest.php</directory>
37+
</testsuite>
38+
<testsuite name="mysqlrelations">
39+
<directory>tests/RelationsTest.php</directory>
3740
<directory>tests/MysqlRelationsTest.php</directory>
3841
</testsuite>
3942
</testsuites>

src/Jenssegers/Eloquent/Model.php

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
use Illuminate\Database\Eloquent\Relations\HasOne;
44
use Illuminate\Database\Eloquent\Relations\HasMany;
5+
use Illuminate\Database\Eloquent\Relations\MorphOne;
6+
use Illuminate\Database\Eloquent\Relations\MorphMany;
7+
use Illuminate\Database\Eloquent\Relations\Relation;
58
use Jenssegers\Mongodb\Relations\BelongsTo;
69
use Jenssegers\Mongodb\Relations\BelongsToMany;
710
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
@@ -33,6 +36,35 @@ public function hasOne($related, $foreignKey = null, $localKey = null)
3336
return new HasOne($instance->newQuery(), $this, $foreignKey, $localKey);
3437
}
3538

39+
/**
40+
* Define a polymorphic one-to-one relationship.
41+
*
42+
* @param string $related
43+
* @param string $name
44+
* @param string $type
45+
* @param string $id
46+
* @param string $localKey
47+
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
48+
*/
49+
public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
50+
{
51+
// Check if it is a relation with an original model.
52+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
53+
{
54+
return parent::morphOne($related, $name, $type, $id, $localKey );
55+
}
56+
57+
$instance = new $related;
58+
59+
list($type, $id) = $this->getMorphs($name, $type, $id);
60+
61+
$table = $instance->getTable();
62+
63+
$localKey = $localKey ?: $this->getKeyName();
64+
65+
return new MorphOne($instance->newQuery(), $this, $type, $id, $localKey);
66+
}
67+
3668
/**
3769
* Define a one-to-many relationship.
3870
*
@@ -58,6 +90,38 @@ public function hasMany($related, $foreignKey = null, $localKey = null)
5890
return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
5991
}
6092

93+
/**
94+
* Define a polymorphic one-to-many relationship.
95+
*
96+
* @param string $related
97+
* @param string $name
98+
* @param string $type
99+
* @param string $id
100+
* @param string $localKey
101+
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
102+
*/
103+
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
104+
{
105+
// Check if it is a relation with an original model.
106+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
107+
{
108+
return parent::morphMany($related, $name, $type, $id, $localKey);
109+
}
110+
111+
$instance = new $related;
112+
113+
// Here we will gather up the morph type and ID for the relationship so that we
114+
// can properly query the intermediate table of a relation. Finally, we will
115+
// get the table and create the relationship instances for the developers.
116+
list($type, $id) = $this->getMorphs($name, $type, $id);
117+
118+
$table = $instance->getTable();
119+
120+
$localKey = $localKey ?: $this->getKeyName();
121+
122+
return new MorphMany($instance->newQuery(), $this, $type, $id, $localKey);
123+
}
124+
61125
/**
62126
* Define an inverse one-to-one or many relationship.
63127
*
@@ -128,9 +192,7 @@ public function belongsToMany($related, $collection = null, $foreignKey = null,
128192
// title of this relation since that is a great convention to apply.
129193
if (is_null($relation))
130194
{
131-
$caller = $this->getBelongsToManyCaller();
132-
133-
$name = $caller['function'];
195+
$relation = $this->getBelongsToManyCaller();
134196
}
135197

136198
// First, we'll need to determine the foreign key and "other key" for the

src/Jenssegers/Mongodb/Model.php

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
<?php namespace Jenssegers\Mongodb;
22

33
use Illuminate\Database\Eloquent\Collection;
4-
use Illuminate\Database\Eloquent\Relations\HasOne;
5-
use Illuminate\Database\Eloquent\Relations\HasMany;
6-
74
use Jenssegers\Mongodb\DatabaseManager as Resolver;
85
use Jenssegers\Mongodb\Eloquent\Builder;
96
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
10-
use Jenssegers\Mongodb\Relations\BelongsTo;
11-
use Jenssegers\Mongodb\Relations\BelongsToMany;
7+
use Jenssegers\Mongodb\Relations\EmbedsMany;
128

139
use Carbon\Carbon;
1410
use DateTime;
@@ -48,7 +44,44 @@ public function getIdAttribute($value)
4844
// If there is an actual id attribute, then return that.
4945
if ($value) return $value;
5046

51-
return $this->getKey();
47+
// Return primary key value if present
48+
if (array_key_exists($this->getKeyName(), $this->attributes)) return $this->attributes[$this->getKeyName()];
49+
}
50+
51+
/**
52+
* Define an embedded one-to-many relationship.
53+
*
54+
* @param string $related
55+
* @param string $collection
56+
* @return \Illuminate\Database\Eloquent\Relations\EmbedsMany
57+
*/
58+
protected function embedsMany($related, $localKey = null, $foreignKey = null, $relation = null)
59+
{
60+
if (is_null($localKey))
61+
{
62+
$localKey = snake_case(str_plural($related)) . '_ids';
63+
}
64+
65+
if (is_null($foreignKey))
66+
{
67+
$foreignKey = snake_case(class_basename($this));
68+
}
69+
70+
// If no relation name was given, we will use this debug backtrace to extract
71+
// the calling method's name and use that as the relationship name as most
72+
// of the time this will be what we desire to use for the relatinoships.
73+
if (is_null($relation))
74+
{
75+
list(, $caller) = debug_backtrace(false);
76+
77+
$relation = $caller['function'];
78+
}
79+
80+
$query = $this->newQuery();
81+
82+
$instance = new $related;
83+
84+
return new EmbedsMany($query, $this, $instance, $localKey, $foreignKey, $relation);
5285
}
5386

5487
/**
@@ -204,6 +237,23 @@ public function dropColumn($columns)
204237
return $query = $this->newQuery()->where($this->getKeyName(), $this->getKey())->unset($columns);
205238
}
206239

240+
/**
241+
* Pass push to the query builder.
242+
*
243+
* @return mixed
244+
*/
245+
public function push()
246+
{
247+
if ($parameters = func_get_args())
248+
{
249+
$query = $this->newQuery();
250+
251+
return call_user_func_array(array($query, 'push'), $parameters);
252+
}
253+
254+
return parent::push();
255+
}
256+
207257
/**
208258
* Create a new Eloquent query builder for the model.
209259
*

src/Jenssegers/Mongodb/Query/Builder.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use DateTime;
77
use Closure;
88

9+
use Illuminate\Database\Query\Expression;
910
use Jenssegers\Mongodb\Connection;
1011

1112
class Builder extends \Illuminate\Database\Query\Builder {
@@ -507,11 +508,19 @@ public function truncate()
507508
*/
508509
public function raw($expression = null)
509510
{
511+
// Execute the closure on the mongodb collection
510512
if ($expression instanceof Closure)
511513
{
512514
return call_user_func($expression, $this->collection);
513515
}
514516

517+
// Create an expression for the given value
518+
else if (!is_null($expression))
519+
{
520+
return new Expression($expression);
521+
}
522+
523+
// Quick access to the mongodb collection
515524
return $this->collection;
516525
}
517526

@@ -631,7 +640,7 @@ protected function performUpdate($query, array $options = array())
631640
* @param mixed $id
632641
* @return mixed
633642
*/
634-
protected function convertKey($id)
643+
public function convertKey($id)
635644
{
636645
if (is_string($id) && strlen($id) === 24 && ctype_xdigit($id))
637646
{

0 commit comments

Comments
 (0)