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
bab6b2d2
Commit
bab6b2d2
authored
Aug 09, 2014
by
Jens Segers
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tweaking belongsToMany relations and push/pull logic, fixes #272
parent
54e6ff97
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
40 deletions
+165
-40
Model.php
src/Jenssegers/Mongodb/Model.php
+79
-3
Builder.php
src/Jenssegers/Mongodb/Query/Builder.php
+9
-2
BelongsToMany.php
src/Jenssegers/Mongodb/Relations/BelongsToMany.php
+45
-34
RelationsTest.php
tests/RelationsTest.php
+32
-1
No files found.
src/Jenssegers/Mongodb/Model.php
View file @
bab6b2d2
...
@@ -358,9 +358,27 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
...
@@ -358,9 +358,27 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
{
{
if
(
$parameters
=
func_get_args
())
if
(
$parameters
=
func_get_args
())
{
{
$unique
=
false
;
if
(
count
(
$parameters
)
==
3
)
{
list
(
$column
,
$values
,
$unique
)
=
$parameters
;
}
else
{
list
(
$column
,
$values
)
=
$parameters
;
}
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
}
$query
=
$this
->
setKeysForSaveQuery
(
$this
->
newQuery
());
$query
=
$this
->
setKeysForSaveQuery
(
$this
->
newQuery
());
return
call_user_func_array
(
array
(
$query
,
'push'
),
$parameters
);
$this
->
pushAttributeValues
(
$column
,
$values
,
$unique
);
return
$query
->
push
(
$column
,
$values
,
$unique
);
}
}
return
parent
::
push
();
return
parent
::
push
();
...
@@ -371,11 +389,69 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
...
@@ -371,11 +389,69 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
*
*
* @return mixed
* @return mixed
*/
*/
public
function
pull
()
public
function
pull
(
$column
,
$values
)
{
{
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
}
$query
=
$this
->
setKeysForSaveQuery
(
$this
->
newQuery
());
$query
=
$this
->
setKeysForSaveQuery
(
$this
->
newQuery
());
return
call_user_func_array
(
array
(
$query
,
'pull'
),
func_get_args
());
$this
->
pullAttributeValues
(
$column
,
$values
);
return
$query
->
pull
(
$column
,
$values
);
}
/**
* Append one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
* @param bool $unique
* @return void
*/
protected
function
pushAttributeValues
(
$column
,
array
$values
,
$unique
=
false
)
{
$current
=
$this
->
getAttributeFromArray
(
$column
)
?:
array
();
foreach
(
$values
as
$value
)
{
// Don't add duplicate values when we only want unique values.
if
(
$unique
and
in_array
(
$value
,
$current
))
continue
;
array_push
(
$current
,
$value
);
}
$this
->
attributes
[
$column
]
=
$current
;
$this
->
syncOriginalAttribute
(
$column
);
}
/**
* Rempove one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
* @return void
*/
protected
function
pullAttributeValues
(
$column
,
array
$values
)
{
$current
=
$this
->
getAttributeFromArray
(
$column
)
?:
array
();
foreach
(
$values
as
$value
)
{
$keys
=
array_keys
(
$current
,
$value
);
foreach
(
$keys
as
$key
)
{
unset
(
$current
[
$key
]);
}
}
$this
->
attributes
[
$column
]
=
$current
;
$this
->
syncOriginalAttribute
(
$column
);
}
}
/**
/**
...
...
src/Jenssegers/Mongodb/Query/Builder.php
View file @
bab6b2d2
...
@@ -519,6 +519,10 @@ class Builder extends \Illuminate\Database\Query\Builder {
...
@@ -519,6 +519,10 @@ class Builder extends \Illuminate\Database\Query\Builder {
{
{
$query
=
array
(
$operator
=>
$column
);
$query
=
array
(
$operator
=>
$column
);
}
}
else
if
(
is_array
(
$value
))
{
$query
=
array
(
$operator
=>
array
(
$column
=>
array
(
'$each'
=>
$value
)));
}
else
else
{
{
$query
=
array
(
$operator
=>
array
(
$column
=>
$value
));
$query
=
array
(
$operator
=>
array
(
$column
=>
$value
));
...
@@ -536,13 +540,16 @@ class Builder extends \Illuminate\Database\Query\Builder {
...
@@ -536,13 +540,16 @@ class Builder extends \Illuminate\Database\Query\Builder {
*/
*/
public
function
pull
(
$column
,
$value
=
null
)
public
function
pull
(
$column
,
$value
=
null
)
{
{
// If we are pulling multiple values, we need to use $pullAll.
$operator
=
is_array
(
$value
)
?
'$pullAll'
:
'$pull'
;
if
(
is_array
(
$column
))
if
(
is_array
(
$column
))
{
{
$query
=
array
(
'$pull'
=>
$column
);
$query
=
array
(
$operator
=>
$column
);
}
}
else
else
{
{
$query
=
array
(
'$pull'
=>
array
(
$column
=>
$value
));
$query
=
array
(
$operator
=>
array
(
$column
=>
$value
));
}
}
return
$this
->
performUpdate
(
$query
);
return
$this
->
performUpdate
(
$query
);
...
...
src/Jenssegers/Mongodb/Relations/BelongsToMany.php
View file @
bab6b2d2
...
@@ -43,12 +43,16 @@ class BelongsToMany extends EloquentBelongsToMany {
...
@@ -43,12 +43,16 @@ class BelongsToMany extends EloquentBelongsToMany {
/**
/**
* Sync the intermediate tables with a list of IDs or collection of models.
* Sync the intermediate tables with a list of IDs or collection of models.
*
*
* @param
array
$ids
* @param
mixed
$ids
* @param bool $detaching
* @param bool $detaching
* @return
void
* @return
array
*/
*/
public
function
sync
(
$ids
,
$detaching
=
true
)
public
function
sync
(
$ids
,
$detaching
=
true
)
{
{
$changes
=
array
(
'attached'
=>
array
(),
'detached'
=>
array
(),
'updated'
=>
array
()
);
if
(
$ids
instanceof
Collection
)
$ids
=
$ids
->
modelKeys
();
if
(
$ids
instanceof
Collection
)
$ids
=
$ids
->
modelKeys
();
// First we need to attach any of the associated models that are not currently
// First we need to attach any of the associated models that are not currently
...
@@ -66,36 +70,36 @@ class BelongsToMany extends EloquentBelongsToMany {
...
@@ -66,36 +70,36 @@ class BelongsToMany extends EloquentBelongsToMany {
if
(
$detaching
and
count
(
$detach
)
>
0
)
if
(
$detaching
and
count
(
$detach
)
>
0
)
{
{
$this
->
detach
(
$detach
);
$this
->
detach
(
$detach
);
$changes
[
'detached'
]
=
(
array
)
array_map
(
'intval'
,
$detach
);
}
}
// Now we are finally ready to attach the new records. Note that we'll disable
// Now we are finally ready to attach the new records. Note that we'll disable
// touching until after the entire operation is complete so we don't fire a
// touching until after the entire operation is complete so we don't fire a
// ton of touch operations until we are totally done syncing the records.
// ton of touch operations until we are totally done syncing the records.
$this
->
attachNew
(
$records
,
$current
,
false
);
$changes
=
array_merge
(
$changes
,
$this
->
attachNew
(
$records
,
$current
,
false
)
);
$this
->
touchIfTouching
();
if
(
count
(
$changes
[
'attached'
])
||
count
(
$changes
[
'updated'
]))
{
$this
->
touchIfTouching
();
}
return
$changes
;
}
}
/**
/**
*
Attach all of the IDs that aren't in the current array
.
*
Update an existing pivot record on the table
.
*
*
* @param
array $records
* @param
mixed $id
* @param array $
current
* @param array $
attributes
* @param bool $touch
* @param bool $touch
* @return void
* @return void
*/
*/
p
rotected
function
attachNew
(
array
$records
,
array
$current
,
$touch
=
true
)
p
ublic
function
updateExistingPivot
(
$id
,
array
$attributes
,
$touch
=
true
)
{
{
foreach
(
$records
as
$id
=>
$attributes
)
// TODO
{
// If the ID is not in the list of existing pivot IDs, we will insert a new pivot
// record, otherwise, we will just update this existing record on this joining
// table, so that the developers will easily update these records pain free.
if
(
!
in_array
(
$id
,
$current
))
{
$this
->
attach
(
$id
,
$attributes
,
$touch
);
}
}
}
}
/**
/**
...
@@ -112,21 +116,21 @@ class BelongsToMany extends EloquentBelongsToMany {
...
@@ -112,21 +116,21 @@ class BelongsToMany extends EloquentBelongsToMany {
$records
=
$this
->
createAttachRecords
((
array
)
$id
,
$attributes
);
$records
=
$this
->
createAttachRecords
((
array
)
$id
,
$attributes
);
// Get the
ID's to attach to the two documents
// Get the
ids to attach to the parent and related model.
$otherIds
=
array_pluck
(
$records
,
$this
->
otherKey
);
$otherIds
=
array_pluck
(
$records
,
$this
->
otherKey
);
$foreignIds
=
array_pluck
(
$records
,
$this
->
foreignKey
);
$foreignIds
=
array_pluck
(
$records
,
$this
->
foreignKey
);
// Attach t
o the parent model
// Attach t
he new ids to the parent model.
$this
->
parent
->
push
(
$this
->
otherKey
,
$otherIds
[
0
]
);
$this
->
parent
->
push
(
$this
->
otherKey
,
$otherIds
,
true
);
// Generate a new related query instance
// Generate a new related query instance
.
$query
=
$this
->
getN
ewRelatedQuery
();
$query
=
$this
->
n
ewRelatedQuery
();
// Set contraints on the related query
// Set contraints on the related query
.
$query
->
where
(
$this
->
related
->
getKeyName
(),
$id
);
$query
->
where
(
$this
->
related
->
getKeyName
(),
$id
);
// Attach t
o the related model
// Attach t
he new ids to the related model.
$query
->
push
(
$this
->
foreignKey
,
$foreignIds
[
0
]
);
$query
->
push
(
$this
->
foreignKey
,
$foreignIds
,
true
);
if
(
$touch
)
$this
->
touchIfTouching
();
if
(
$touch
)
$this
->
touchIfTouching
();
}
}
...
@@ -142,18 +146,15 @@ class BelongsToMany extends EloquentBelongsToMany {
...
@@ -142,18 +146,15 @@ class BelongsToMany extends EloquentBelongsToMany {
{
{
if
(
$ids
instanceof
Model
)
$ids
=
(
array
)
$ids
->
getKey
();
if
(
$ids
instanceof
Model
)
$ids
=
(
array
)
$ids
->
getKey
();
$query
=
$this
->
getN
ewRelatedQuery
();
$query
=
$this
->
n
ewRelatedQuery
();
// If associated IDs were passed to the method we will only delete those
// If associated IDs were passed to the method we will only delete those
// associations, otherwise all of the association ties will be broken.
// associations, otherwise all of the association ties will be broken.
// We'll return the numbers of affected rows when we do the deletes.
// We'll return the numbers of affected rows when we do the deletes.
$ids
=
(
array
)
$ids
;
$ids
=
(
array
)
$ids
;
// Pull each id from the parent.
// Detach all ids from the parent model.
foreach
(
$ids
as
$id
)
$this
->
parent
->
pull
(
$this
->
otherKey
,
$ids
);
{
$this
->
parent
->
pull
(
$this
->
otherKey
,
$id
);
}
// Prepare the query to select all related objects.
// Prepare the query to select all related objects.
if
(
count
(
$ids
)
>
0
)
if
(
count
(
$ids
)
>
0
)
...
@@ -196,11 +197,21 @@ class BelongsToMany extends EloquentBelongsToMany {
...
@@ -196,11 +197,21 @@ class BelongsToMany extends EloquentBelongsToMany {
}
}
/**
/**
* Get a new related query.
* Create a new query builder for the related model.
*
* @return \Illuminate\Database\Query\Builder
*/
protected
function
newPivotQuery
()
{
return
$this
->
newRelatedQuery
();
}
/**
* Create a new query builder for the related model.
*
*
* @return \Illuminate\Database\Query\Builder
* @return \Illuminate\Database\Query\Builder
*/
*/
public
function
getN
ewRelatedQuery
()
public
function
n
ewRelatedQuery
()
{
{
return
$this
->
related
->
newQuery
();
return
$this
->
related
->
newQuery
();
}
}
...
...
tests/RelationsTest.php
View file @
bab6b2d2
...
@@ -417,7 +417,7 @@ class RelationsTest extends TestCase {
...
@@ -417,7 +417,7 @@ class RelationsTest extends TestCase {
$this
->
assertEquals
(
'Paris'
,
$address
->
data
[
'city'
]);
$this
->
assertEquals
(
'Paris'
,
$address
->
data
[
'city'
]);
}
}
public
function
testDoubleSave
()
public
function
testDoubleSave
OneToMany
()
{
{
$author
=
User
::
create
(
array
(
'name'
=>
'George R. R. Martin'
));
$author
=
User
::
create
(
array
(
'name'
=>
'George R. R. Martin'
));
$book
=
Book
::
create
(
array
(
'title'
=>
'A Game of Thrones'
));
$book
=
Book
::
create
(
array
(
'title'
=>
'A Game of Thrones'
));
...
@@ -426,14 +426,45 @@ class RelationsTest extends TestCase {
...
@@ -426,14 +426,45 @@ class RelationsTest extends TestCase {
$author
->
books
()
->
save
(
$book
);
$author
->
books
()
->
save
(
$book
);
$author
->
save
();
$author
->
save
();
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
$author
->
_id
,
$book
->
author_id
);
$author
=
User
::
where
(
'name'
,
'George R. R. Martin'
)
->
first
();
$author
=
User
::
where
(
'name'
,
'George R. R. Martin'
)
->
first
();
$book
=
Book
::
where
(
'title'
,
'A Game of Thrones'
)
->
first
();
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
$author
->
_id
,
$book
->
author_id
);
$author
->
books
()
->
save
(
$book
);
$author
->
books
()
->
save
(
$book
);
$author
->
books
()
->
save
(
$book
);
$author
->
books
()
->
save
(
$book
);
$author
->
save
();
$author
->
save
();
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
1
,
$author
->
books
()
->
count
());
$this
->
assertEquals
(
$author
->
_id
,
$book
->
author_id
);
}
public
function
testDoubleSaveManyToMany
()
{
$user
=
User
::
create
(
array
(
'name'
=>
'John Doe'
));
$client
=
Client
::
create
(
array
(
'name'
=>
'Admins'
));
$user
->
clients
()
->
save
(
$client
);
$user
->
clients
()
->
save
(
$client
);
$user
->
save
();
$this
->
assertEquals
(
1
,
$user
->
clients
()
->
count
());
//$this->assertEquals(array($user->_id), $client->user_ids); TODO
$this
->
assertEquals
(
array
(
$client
->
_id
),
$user
->
client_ids
);
$user
=
User
::
where
(
'name'
,
'John Doe'
)
->
first
();
$client
=
Client
::
where
(
'name'
,
'Admins'
)
->
first
();
$this
->
assertEquals
(
1
,
$user
->
clients
()
->
count
());
//$this->assertEquals(array($user->_id), $client->user_ids); TODO
$this
->
assertEquals
(
array
(
$client
->
_id
),
$user
->
client_ids
);
$user
->
clients
()
->
save
(
$client
);
$user
->
clients
()
->
save
(
$client
);
$user
->
save
();
$this
->
assertEquals
(
1
,
$user
->
clients
()
->
count
());
//$this->assertEquals(array($user->_id), $client->user_ids); TODO
$this
->
assertEquals
(
array
(
$client
->
_id
),
$user
->
client_ids
);
}
}
}
}
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