Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
laravel-mongodb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
laravel-mongodb
Commits
b9e4cdae
Commit
b9e4cdae
authored
Apr 12, 2014
by
Jens Segers
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tweaking relations and MongoId conversion
parent
9443e8b4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
276 additions
and
396 deletions
+276
-396
Model.php
src/Jenssegers/Mongodb/Model.php
+14
-18
Builder.php
src/Jenssegers/Mongodb/Query/Builder.php
+5
-5
BelongsToMany.php
src/Jenssegers/Mongodb/Relations/BelongsToMany.php
+8
-32
EmbedsMany.php
src/Jenssegers/Mongodb/Relations/EmbedsMany.php
+193
-175
MorphTo.php
src/Jenssegers/Mongodb/Relations/MorphTo.php
+14
-161
ModelTest.php
tests/ModelTest.php
+10
-0
QueryBuilderTest.php
tests/QueryBuilderTest.php
+1
-3
RelationsTest.php
tests/RelationsTest.php
+28
-2
TestCase.php
tests/TestCase.php
+3
-0
No files found.
src/Jenssegers/Mongodb/Model.php
View file @
b9e4cdae
...
...
@@ -169,27 +169,23 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
}
/**
*
Set the array of model attributes. No checking is done
.
*
Get an attribute from the model
.
*
* @param array $attributes
* @param bool $sync
* @return void
* @param string $key
* @return mixed
*/
public
function
setRawAttributes
(
array
$attributes
,
$sync
=
false
)
public
function
getAttribute
(
$key
)
{
foreach
(
$attributes
as
$key
=>
&
$value
)
$attribute
=
parent
::
getAttribute
(
$key
);
// If the attribute is a MongoId object, return it as a string.
// This is makes Eloquent relations a lot easier.
if
(
$attribute
instanceof
MongoId
)
{
/**
* MongoIds are converted to string to make it easier to pass
* the id to other instances or relations.
*/
if
(
$value
instanceof
MongoId
)
{
$value
=
(
string
)
$value
;
}
return
(
string
)
$attribute
;
}
parent
::
setRawAttributes
(
$attributes
,
$sync
)
;
return
$attribute
;
}
/**
...
...
@@ -223,7 +219,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
* @param mixed $columns
* @return int
*/
public
function
drop
Column
(
$columns
)
public
function
drop
(
$columns
)
{
if
(
!
is_array
(
$columns
))
$columns
=
array
(
$columns
);
...
...
@@ -234,7 +230,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
}
// Perform unset only on current document
return
$
query
=
$
this
->
newQuery
()
->
where
(
$this
->
getKeyName
(),
$this
->
getKey
())
->
unset
(
$columns
);
return
$this
->
newQuery
()
->
where
(
$this
->
getKeyName
(),
$this
->
getKey
())
->
unset
(
$columns
);
}
/**
...
...
@@ -289,7 +285,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
// Unset method
if
(
$method
==
'unset'
)
{
return
call_user_func_array
(
array
(
$this
,
'drop
Column
'
),
$parameters
);
return
call_user_func_array
(
array
(
$this
,
'drop'
),
$parameters
);
}
return
parent
::
__call
(
$method
,
$parameters
);
...
...
src/Jenssegers/Mongodb/Query/Builder.php
View file @
b9e4cdae
...
...
@@ -59,7 +59,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
/**
* Execute a query for a single record by ID.
*
* @param
int
$id
* @param
mixed
$id
* @param array $columns
* @return mixed
*/
...
...
@@ -377,8 +377,8 @@ class Builder extends \Illuminate\Database\Query\Builder {
$sequence
=
'_id'
;
}
// Return id
as a string
return
(
string
)
$values
[
$sequence
];
// Return id
return
$values
[
$sequence
];
}
}
...
...
@@ -585,7 +585,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
* @param mixed $columns
* @return int
*/
public
function
drop
Column
(
$columns
)
public
function
drop
(
$columns
)
{
if
(
!
is_array
(
$columns
))
$columns
=
array
(
$columns
);
...
...
@@ -846,7 +846,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
{
if
(
$method
==
'unset'
)
{
return
call_user_func_array
(
array
(
$this
,
'drop
Column
'
),
$parameters
);
return
call_user_func_array
(
array
(
$this
,
'drop'
),
$parameters
);
}
return
parent
::
__call
(
$method
,
$parameters
);
...
...
src/Jenssegers/Mongodb/Relations/BelongsToMany.php
View file @
b9e4cdae
<?php
namespace
Jenssegers\Mongodb\Relations
;
use
Illuminate\Database\Eloquent\Collection
;
use
Jenssegers\Mongodb\Model
;
use
Illuminate\Database\Eloquent\Collection
;
use
Illuminate\Database\Eloquent\Relations\BelongsToMany
as
EloquentBelongsToMany
;
class
BelongsToMany
extends
EloquentBelongsToMany
{
...
...
@@ -36,12 +36,12 @@ class BelongsToMany extends EloquentBelongsToMany {
{
if
(
static
::
$constraints
)
{
$this
->
query
->
where
(
$this
->
foreignKey
,
$this
->
parent
->
getKey
());
$this
->
query
->
where
(
$this
->
getForeignKey
(),
'='
,
$this
->
parent
->
getKey
());
}
}
/**
* Sync the intermediate tables with a list of IDs.
* Sync the intermediate tables with a list of IDs
or collection of models
.
*
* @param array $ids
* @param bool $detaching
...
...
@@ -49,14 +49,12 @@ class BelongsToMany extends EloquentBelongsToMany {
*/
public
function
sync
(
array
$ids
,
$detaching
=
true
)
{
if
(
$ids
instanceof
Collection
)
$ids
=
$ids
->
modelKeys
();
// First we need to attach any of the associated models that are not currently
// in this joining table. We'll spin through the given IDs, checking to see
// if they exist in the array of current ones, and if not we will insert.
$current
=
$this
->
parent
->
{
$this
->
otherKey
};
// Check if the current array exists or not on the parent model and create it
// if it does not exist
if
(
is_null
(
$current
))
$current
=
array
();
$current
=
$this
->
parent
->
{
$this
->
otherKey
}
?:
array
();
$records
=
$this
->
formatSyncList
(
$ids
);
...
...
@@ -133,27 +131,6 @@ class BelongsToMany extends EloquentBelongsToMany {
if
(
$touch
)
$this
->
touchIfTouching
();
}
/**
* Create an array of records to insert into the pivot table.
*
* @param array $ids
* @return void
*/
protected
function
createAttachRecords
(
$ids
,
array
$attributes
)
{
$records
=
array
();
// To create the attachment records, we will simply spin through the IDs given
// and create a new record to insert for each ID. Each ID may actually be a
// key in the array, with extra attributes to be placed in other columns.
foreach
(
$ids
as
$key
=>
$value
)
{
$records
[]
=
$this
->
attacher
(
$key
,
$value
,
$attributes
,
false
);
}
return
$records
;
}
/**
* Detach models from the relationship.
*
...
...
@@ -165,6 +142,8 @@ class BelongsToMany extends EloquentBelongsToMany {
{
if
(
$ids
instanceof
Model
)
$ids
=
(
array
)
$ids
->
getKey
();
$query
=
$this
->
getNewRelatedQuery
();
// If associated IDs were passed to the method we will only delete those
// associations, otherwise all of the association ties will be broken.
// We'll return the numbers of affected rows when we do the deletes.
...
...
@@ -176,9 +155,6 @@ class BelongsToMany extends EloquentBelongsToMany {
$this
->
parent
->
pull
(
$this
->
otherKey
,
$id
);
}
// Get a new related query.
$query
=
$this
->
getNewRelatedQuery
();
// Prepare the query to select all related objects.
if
(
count
(
$ids
)
>
0
)
{
...
...
src/Jenssegers/Mongodb/Relations/EmbedsMany.php
View file @
b9e4cdae
This diff is collapsed.
Click to expand it.
src/Jenssegers/Mongodb/Relations/MorphTo.php
View file @
b9e4cdae
<?php
namespace
Jenssegers\Mongodb\Relations
;
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Database\Eloquent\Builder
;
use
Illuminate\Database\Query\Expression
;
use
Illuminate\Database\Eloquent\Collection
;
use
Illuminate\
Support\Collection
as
BaseCollection
;
use
Illuminate\
Database\Eloquent\Relations\MorphTo
as
EloquentMorphTo
;
class
MorphTo
extends
Belongs
To
{
class
MorphTo
extends
EloquentMorph
To
{
/**
* The type of the polymorphic relation.
*
* @var string
*/
protected
$morphType
;
/**
* The models whose relations are being eager loaded.
*
* @var \Illuminate\Database\Eloquent\Collection
*/
protected
$models
;
/**
* All of the models keyed by ID.
*
* @var array
*/
protected
$dictionary
=
array
();
/**
* Create a new belongs to relationship instance.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $otherKey
* @param string $type
* @param string $relation
* @return void
*/
public
function
__construct
(
Builder
$query
,
Model
$parent
,
$foreignKey
,
$otherKey
,
$type
,
$relation
)
* Set the base constraints on the relation query.
*
* @return void
*/
public
function
addConstraints
()
{
$this
->
morphType
=
$type
;
parent
::
__construct
(
$query
,
$parent
,
$foreignKey
,
$otherKey
,
$relation
);
if
(
static
::
$constraints
)
{
// For belongs to relationships, which are essentially the inverse of has one
// or has many relationships, we need to actually query on the primary key
// of the related models matching on the foreign key that's on a parent.
$this
->
query
->
where
(
$this
->
otherKey
,
'='
,
$this
->
parent
->
{
$this
->
foreignKey
});
}
}
/**
...
...
@@ -58,125 +32,4 @@ class MorphTo extends BelongsTo {
$this
->
buildDictionary
(
$this
->
models
=
Collection
::
make
(
$models
));
}
/**
* Buiild a dictionary with the models.
*
* @param \Illuminate\Database\Eloquent\Models $models
* @return void
*/
protected
function
buildDictionary
(
Collection
$models
)
{
foreach
(
$models
as
$model
)
{
if
(
$model
->
{
$this
->
morphType
})
{
$this
->
dictionary
[
$model
->
{
$this
->
morphType
}][
$model
->
{
$this
->
foreignKey
}][]
=
$model
;
}
}
}
/**
* Match the eagerly loaded results to their parents.
*
* @param array $models
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @return array
*/
public
function
match
(
array
$models
,
Collection
$results
,
$relation
)
{
return
$models
;
}
/**
* Get the results of the relationship.
*
* Called via eager load method of Eloquent query builder.
*
* @return mixed
*/
public
function
getEager
()
{
foreach
(
array_keys
(
$this
->
dictionary
)
as
$type
)
{
$this
->
matchToMorphParents
(
$type
,
$this
->
getResultsByType
(
$type
));
}
return
$this
->
models
;
}
/**
* Match the results for a given type to their parents.
*
* @param string $type
* @param \Illuminate\Database\Eloquent\Collection $results
* @return void
*/
protected
function
matchToMorphParents
(
$type
,
Collection
$results
)
{
foreach
(
$results
as
$result
)
{
if
(
isset
(
$this
->
dictionary
[
$type
][
$result
->
getKey
()]))
{
foreach
(
$this
->
dictionary
[
$type
][
$result
->
getKey
()]
as
$model
)
{
$model
->
setRelation
(
$this
->
relation
,
$result
);
}
}
}
}
/**
* Get all of the relation results for a type.
*
* @param string $type
* @return \Illuminate\Database\Eloquent\Collection
*/
protected
function
getResultsByType
(
$type
)
{
$instance
=
$this
->
createModelByType
(
$type
);
$key
=
$instance
->
getKeyName
();
return
$instance
->
whereIn
(
$key
,
$this
->
gatherKeysByType
(
$type
)
->
all
())
->
get
();
}
/**
* Gather all of the foreign keys for a given type.
*
* @param string $type
* @return array
*/
protected
function
gatherKeysByType
(
$type
)
{
$foreign
=
$this
->
foreignKey
;
return
BaseCollection
::
make
(
$this
->
dictionary
[
$type
])
->
map
(
function
(
$models
)
use
(
$foreign
)
{
return
head
(
$models
)
->
{
$foreign
};
})
->
unique
();
}
/**
* Create a new model instance by type.
*
* @param string $type
* @return \Illuminate\Database\Eloquent\Model
*/
public
function
createModelByType
(
$type
)
{
return
new
$type
;
}
/**
* Get the dictionary used by the relationship.
*
* @return array
*/
public
function
getDictionary
()
{
return
$this
->
dictionary
;
}
}
tests/ModelTest.php
View file @
b9e4cdae
...
...
@@ -34,10 +34,14 @@ class ModelTest extends TestCase {
$this
->
assertEquals
(
1
,
User
::
count
());
$this
->
assertTrue
(
isset
(
$user
->
_id
));
$this
->
assertTrue
(
is_string
(
$user
->
_id
));
$this
->
assertNotEquals
(
''
,
(
string
)
$user
->
_id
);
$this
->
assertNotEquals
(
0
,
strlen
((
string
)
$user
->
_id
));
$this
->
assertInstanceOf
(
'Carbon\Carbon'
,
$user
->
created_at
);
$raw
=
$user
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
$this
->
assertEquals
(
'John Doe'
,
$user
->
name
);
$this
->
assertEquals
(
35
,
$user
->
age
);
}
...
...
@@ -50,6 +54,9 @@ class ModelTest extends TestCase {
$user
->
age
=
35
;
$user
->
save
();
$raw
=
$user
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
$check
=
User
::
find
(
$user
->
_id
);
$check
->
age
=
36
;
...
...
@@ -65,6 +72,9 @@ class ModelTest extends TestCase {
$user
->
update
(
array
(
'age'
=>
20
));
$raw
=
$user
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
$check
=
User
::
find
(
$user
->
_id
);
$this
->
assertEquals
(
20
,
$check
->
age
);
}
...
...
tests/QueryBuilderTest.php
View file @
b9e4cdae
...
...
@@ -54,9 +54,7 @@ class QueryBuilderTest extends TestCase {
public
function
testInsertGetId
()
{
$id
=
DB
::
collection
(
'users'
)
->
insertGetId
(
array
(
'name'
=>
'John Doe'
));
$this
->
assertTrue
(
is_string
(
$id
));
$this
->
assertEquals
(
24
,
strlen
(
$id
));
$this
->
assertInstanceOf
(
'MongoId'
,
$id
);
}
public
function
testBatchInsert
()
...
...
tests/RelationsTest.php
View file @
b9e4cdae
...
...
@@ -308,6 +308,10 @@ class RelationsTest extends TestCase {
$this
->
assertInstanceOf
(
'DateTime'
,
$address
->
created_at
);
$this
->
assertInstanceOf
(
'DateTime'
,
$address
->
updated_at
);
$this
->
assertNotNull
(
$address
->
_id
);
$this
->
assertTrue
(
is_string
(
$address
->
_id
));
$raw
=
$address
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
$address
=
$user
->
addresses
()
->
save
(
new
Address
(
array
(
'city'
=>
'Paris'
)));
...
...
@@ -410,15 +414,21 @@ class RelationsTest extends TestCase {
$user
=
User
::
create
(
array
());
$address
=
$user
->
addresses
()
->
create
(
array
(
'city'
=>
'Bruxelles'
));
$this
->
assertInstanceOf
(
'Address'
,
$address
);
$this
->
assert
InstanceOf
(
'MongoID'
,
$address
->
_id
);
$this
->
assert
True
(
is_string
(
$address
->
_id
)
);
$this
->
assertEquals
(
array
(
'Bruxelles'
),
$user
->
addresses
->
lists
(
'city'
));
$raw
=
$address
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
$freshUser
=
User
::
find
(
$user
->
id
);
$this
->
assertEquals
(
array
(
'Bruxelles'
),
$freshUser
->
addresses
->
lists
(
'city'
));
$user
=
User
::
create
(
array
());
$address
=
$user
->
addresses
()
->
create
(
array
(
'_id'
=>
''
,
'city'
=>
'Bruxelles'
));
$this
->
assertInstanceOf
(
'MongoID'
,
$address
->
_id
);
$this
->
assertTrue
(
is_string
(
$address
->
_id
));
$raw
=
$address
->
getAttributes
();
$this
->
assertInstanceOf
(
'MongoId'
,
$raw
[
'_id'
]);
}
public
function
testEmbedsManyCreateMany
()
...
...
@@ -553,4 +563,20 @@ class RelationsTest extends TestCase {
$address
->
unsetEventDispatcher
();
}
public
function
testEmbedsManyFindOrContains
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$address1
=
$user
->
addresses
()
->
save
(
new
Address
(
array
(
'city'
=>
'New York'
)));
$address2
=
$user
->
addresses
()
->
save
(
new
Address
(
array
(
'city'
=>
'Paris'
)));
$address
=
$user
->
addresses
()
->
find
(
$address1
->
_id
);
$this
->
assertEquals
(
$address
->
city
,
$address1
->
city
);
$address
=
$user
->
addresses
()
->
find
(
$address2
->
_id
);
$this
->
assertEquals
(
$address
->
city
,
$address2
->
city
);
$this
->
assertTrue
(
$user
->
addresses
()
->
contains
(
$address2
->
_id
));
$this
->
assertFalse
(
$user
->
addresses
()
->
contains
(
'123'
));
}
}
tests/TestCase.php
View file @
b9e4cdae
...
...
@@ -32,6 +32,9 @@ class TestCase extends Orchestra\Testbench\TestCase {
// overwrite database configuration
$app
[
'config'
]
->
set
(
'database.connections.mysql'
,
$config
[
'connections'
][
'mysql'
]);
$app
[
'config'
]
->
set
(
'database.connections.mongodb'
,
$config
[
'connections'
][
'mongodb'
]);
// overwrite cache configuration
$app
[
'config'
]
->
set
(
'cache.driver'
,
'array'
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment