Skip to content

Commit f037b6a

Browse files
committed
Testing new 2-way-relationships
1 parent 765e667 commit f037b6a

File tree

11 files changed

+308
-165
lines changed

11 files changed

+308
-165
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ services: mongodb
1313

1414
before_script:
1515
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
16+
- mysql -e 'create database phpunit;'
1617
- composer self-update
1718
- composer install --dev --no-interaction
1819

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
},
2222
"autoload": {
2323
"psr-0": {
24-
"Jenssegers\\Mongodb": "src/"
24+
"Jenssegers\\Mongodb": "src/",
25+
"Jenssegers\\Eloquent": "src/"
2526
}
2627
},
2728
"minimum-stability": "dev"

src/Jenssegers/Eloquent/Model.php

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<?php namespace Jenssegers\Eloquent;
2+
3+
use Illuminate\Database\Eloquent\Relations\HasOne;
4+
use Illuminate\Database\Eloquent\Relations\HasMany;
5+
use Jenssegers\Mongodb\Relations\BelongsTo;
6+
use Jenssegers\Mongodb\Relations\BelongsToMany;
7+
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
8+
9+
abstract class Model extends \Illuminate\Database\Eloquent\Model {
10+
11+
/**
12+
* Define a one-to-one relationship.
13+
*
14+
* @param string $related
15+
* @param string $foreignKey
16+
* @param string $localKey
17+
* @return \Illuminate\Database\Eloquent\Relations\HasOne
18+
*/
19+
public function hasOne($related, $foreignKey = null, $localKey = null)
20+
{
21+
// Check if it is a relation with an original model.
22+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
23+
{
24+
return parent::hasOne($related, $foreignKey, $localKey);
25+
}
26+
27+
$foreignKey = $foreignKey ?: $this->getForeignKey();
28+
29+
$instance = new $related;
30+
31+
$localKey = $localKey ?: $this->getKeyName();
32+
33+
return new HasOne($instance->newQuery(), $this, $foreignKey, $localKey);
34+
}
35+
36+
/**
37+
* Define a one-to-many relationship.
38+
*
39+
* @param string $related
40+
* @param string $foreignKey
41+
* @param string $localKey
42+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
43+
*/
44+
public function hasMany($related, $foreignKey = null, $localKey = null)
45+
{
46+
// Check if it is a relation with an original model.
47+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
48+
{
49+
return parent::hasMany($related, $foreignKey, $localKey);
50+
}
51+
52+
$foreignKey = $foreignKey ?: $this->getForeignKey();
53+
54+
$instance = new $related;
55+
56+
$localKey = $localKey ?: $this->getKeyName();
57+
58+
return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
59+
}
60+
61+
/**
62+
* Define an inverse one-to-one or many relationship.
63+
*
64+
* @param string $related
65+
* @param string $foreignKey
66+
* @param string $otherKey
67+
* @param string $relation
68+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
69+
*/
70+
public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
71+
{
72+
// Check if it is a relation with an original model.
73+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
74+
{
75+
return parent::belongsTo($related, $foreignKey, $otherKey, $relation);
76+
}
77+
78+
// If no relation name was given, we will use this debug backtrace to extract
79+
// the calling method's name and use that as the relationship name as most
80+
// of the time this will be what we desire to use for the relatinoships.
81+
if (is_null($relation))
82+
{
83+
list(, $caller) = debug_backtrace(false);
84+
85+
$relation = $caller['function'];
86+
}
87+
88+
// If no foreign key was supplied, we can use a backtrace to guess the proper
89+
// foreign key name by using the name of the relationship function, which
90+
// when combined with an "_id" should conventionally match the columns.
91+
if (is_null($foreignKey))
92+
{
93+
$foreignKey = snake_case($relation).'_id';
94+
}
95+
96+
$instance = new $related;
97+
98+
// Once we have the foreign key names, we'll just create a new Eloquent query
99+
// for the related models and returns the relationship instance which will
100+
// actually be responsible for retrieving and hydrating every relations.
101+
$query = $instance->newQuery();
102+
103+
$otherKey = $otherKey ?: $instance->getKeyName();
104+
105+
return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
106+
}
107+
108+
/**
109+
* Define a many-to-many relationship.
110+
*
111+
* @param string $related
112+
* @param string $collection
113+
* @param string $foreignKey
114+
* @param string $otherKey
115+
* @param string $relation
116+
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
117+
*/
118+
public function belongsToMany($related, $collection = null, $foreignKey = null, $otherKey = null, $relation = null)
119+
{
120+
// Check if it is a relation with an original model.
121+
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
122+
{
123+
return parent::belongsToMany($related, $collection, $foreignKey, $otherKey, $relation);
124+
}
125+
126+
// If no relationship name was passed, we will pull backtraces to get the
127+
// name of the calling function. We will use that function name as the
128+
// title of this relation since that is a great convention to apply.
129+
if (is_null($relation))
130+
{
131+
$caller = $this->getBelongsToManyCaller();
132+
133+
$name = $caller['function'];
134+
}
135+
136+
// First, we'll need to determine the foreign key and "other key" for the
137+
// relationship. Once we have determined the keys we'll make the query
138+
// instances as well as the relationship instances we need for this.
139+
$foreignKey = $foreignKey ?: $this->getForeignKey() . 's';
140+
141+
$instance = new $related;
142+
143+
$otherKey = $otherKey ?: $instance->getForeignKey() . 's';
144+
145+
// If no table name was provided, we can guess it by concatenating the two
146+
// models using underscores in alphabetical order. The two model names
147+
// are transformed to snake case from their default CamelCase also.
148+
if (is_null($collection))
149+
{
150+
$collection = $instance->getTable();
151+
}
152+
153+
// Now we're ready to create a new query builder for the related model and
154+
// the relationship instances for the relation. The relations will set
155+
// appropriate query constraint and entirely manages the hydrations.
156+
$query = $instance->newQuery();
157+
158+
return new BelongsToMany($query, $this, $collection, $foreignKey, $otherKey, $relation);
159+
}
160+
161+
/**
162+
* Get a new query builder instance for the connection.
163+
*
164+
* @return Builder
165+
*/
166+
protected function newBaseQueryBuilder()
167+
{
168+
$connection = $this->getConnection();
169+
170+
// Check the connection type
171+
if ($connection instanceof \Jenssegers\Mongodb\Connection)
172+
{
173+
return new QueryBuilder($connection);
174+
}
175+
176+
return parent::newBaseQueryBuilder();
177+
}
178+
179+
}

src/Jenssegers/Mongodb/Model.php

Lines changed: 1 addition & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use MongoId;
1515
use MongoDate;
1616

17-
abstract class Model extends \Illuminate\Database\Eloquent\Model {
17+
abstract class Model extends \Jenssegers\Eloquent\Model {
1818

1919
/**
2020
* The collection associated with the model.
@@ -121,166 +121,6 @@ public function getTable()
121121
return parent::getTable();
122122
}
123123

124-
/**
125-
* Define a one-to-one relationship.
126-
*
127-
* @param string $related
128-
* @param string $foreignKey
129-
* @param string $localKey
130-
* @return \Illuminate\Database\Eloquent\Relations\HasOne
131-
*/
132-
public function hasOne($related, $foreignKey = null, $localKey = null)
133-
{
134-
// Check if it is a relation with an original model.
135-
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
136-
{
137-
return parent::hasOne($related, $foreignKey, $localKey);
138-
}
139-
140-
$foreignKey = $foreignKey ?: $this->getForeignKey();
141-
142-
$instance = new $related;
143-
144-
$localKey = $localKey ?: $this->getKeyName();
145-
146-
return new HasOne($instance->newQuery(), $this, $foreignKey, $localKey);
147-
}
148-
149-
/**
150-
* Define a one-to-many relationship.
151-
*
152-
* @param string $related
153-
* @param string $foreignKey
154-
* @param string $localKey
155-
* @return \Illuminate\Database\Eloquent\Relations\HasMany
156-
*/
157-
public function hasMany($related, $foreignKey = null, $localKey = null)
158-
{
159-
// Check if it is a relation with an original model.
160-
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
161-
{
162-
return parent::hasMany($related, $foreignKey, $localKey);
163-
}
164-
165-
$foreignKey = $foreignKey ?: $this->getForeignKey();
166-
167-
$instance = new $related;
168-
169-
$localKey = $localKey ?: $this->getKeyName();
170-
171-
return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
172-
}
173-
174-
/**
175-
* Define an inverse one-to-one or many relationship.
176-
*
177-
* @param string $related
178-
* @param string $foreignKey
179-
* @param string $otherKey
180-
* @param string $relation
181-
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
182-
*/
183-
public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
184-
{
185-
// Check if it is a relation with an original model.
186-
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
187-
{
188-
return parent::belongsTo($related, $foreignKey, $otherKey, $relation);
189-
}
190-
191-
// If no relation name was given, we will use this debug backtrace to extract
192-
// the calling method's name and use that as the relationship name as most
193-
// of the time this will be what we desire to use for the relatinoships.
194-
if (is_null($relation))
195-
{
196-
list(, $caller) = debug_backtrace(false);
197-
198-
$relation = $caller['function'];
199-
}
200-
201-
// If no foreign key was supplied, we can use a backtrace to guess the proper
202-
// foreign key name by using the name of the relationship function, which
203-
// when combined with an "_id" should conventionally match the columns.
204-
if (is_null($foreignKey))
205-
{
206-
$foreignKey = snake_case($relation).'_id';
207-
}
208-
209-
$instance = new $related;
210-
211-
// Once we have the foreign key names, we'll just create a new Eloquent query
212-
// for the related models and returns the relationship instance which will
213-
// actually be responsible for retrieving and hydrating every relations.
214-
$query = $instance->newQuery();
215-
216-
$otherKey = $otherKey ?: $instance->getKeyName();
217-
218-
return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
219-
}
220-
221-
/**
222-
* Define a many-to-many relationship.
223-
*
224-
* @param string $related
225-
* @param string $collection
226-
* @param string $foreignKey
227-
* @param string $otherKey
228-
* @param string $relation
229-
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
230-
*/
231-
public function belongsToMany($related, $collection = null, $foreignKey = null, $otherKey = null, $relation = null)
232-
{
233-
// Check if it is a relation with an original model.
234-
if (!is_subclass_of($related, 'Jenssegers\Mongodb\Model'))
235-
{
236-
return parent::belongsToMany($related, $collection, $foreignKey, $otherKey, $relation);
237-
}
238-
239-
// If no relationship name was passed, we will pull backtraces to get the
240-
// name of the calling function. We will use that function name as the
241-
// title of this relation since that is a great convention to apply.
242-
if (is_null($relation))
243-
{
244-
$caller = $this->getBelongsToManyCaller();
245-
246-
$name = $caller['function'];
247-
}
248-
249-
// First, we'll need to determine the foreign key and "other key" for the
250-
// relationship. Once we have determined the keys we'll make the query
251-
// instances as well as the relationship instances we need for this.
252-
$foreignKey = $foreignKey ?: $this->getForeignKey() . 's';
253-
254-
$instance = new $related;
255-
256-
$otherKey = $otherKey ?: $instance->getForeignKey() . 's';
257-
258-
// If no table name was provided, we can guess it by concatenating the two
259-
// models using underscores in alphabetical order. The two model names
260-
// are transformed to snake case from their default CamelCase also.
261-
if (is_null($collection))
262-
{
263-
$collection = $instance->getTable();
264-
}
265-
266-
// Now we're ready to create a new query builder for the related model and
267-
// the relationship instances for the relation. The relations will set
268-
// appropriate query constraint and entirely manages the hydrations.
269-
$query = $instance->newQuery();
270-
271-
return new BelongsToMany($query, $this, $collection, $foreignKey, $otherKey, $relation);
272-
}
273-
274-
/**
275-
* Get a new query builder instance for the connection.
276-
*
277-
* @return Builder
278-
*/
279-
protected function newBaseQueryBuilder()
280-
{
281-
return new QueryBuilder($this->getConnection());
282-
}
283-
284124
/**
285125
* Set the array of model attributes. No checking is done.
286126
*

tests/ModelTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public function testNewModel()
1616
{
1717
$user = new User;
1818
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $user);
19+
$this->assertInstanceOf('Jenssegers\Mongodb\Connection', $user->getConnection());
1920
$this->assertEquals(false, $user->exists);
2021
$this->assertEquals('users', $user->getTable());
2122
$this->assertEquals('_id', $user->getKeyName());

0 commit comments

Comments
 (0)