Skip to content

Commit c8464b9

Browse files
author
phoenix
committed
feature -- experimental support of HasMany and BelongsTo relations
1 parent 717d29a commit c8464b9

File tree

14 files changed

+311
-34
lines changed

14 files changed

+311
-34
lines changed

dist/js/field.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/js/components/DetailField.vue

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
</template>
2626

2727
<script>
28-
import {FormField, HandlesValidationErrors} from 'laravel-nova'
28+
import { FormField, HandlesValidationErrors } from "laravel-nova";
2929
30-
import Treeselect from '@riophae/vue-treeselect'
31-
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
30+
import Treeselect from "@riophae/vue-treeselect";
31+
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
3232
3333
export default {
3434
components: {Treeselect},
@@ -39,7 +39,7 @@ export default {
3939
data()
4040
{
4141
return {
42-
selectedValues: [],
42+
selectedValues: null,
4343
};
4444
},
4545
methods: {
@@ -56,17 +56,31 @@ export default {
5656
},
5757
setInitialValue()
5858
{
59+
let baseUrl = '/nova-vendor/nova-nested-tree-attach-many/';
5960
60-
let baseUrl = '/nova-vendor/nova-nested-tree-attach-many/';
61+
if( this.resourceId )
62+
{
63+
const url = [
64+
baseUrl + this.resourceName,
65+
this.resourceId,
66+
"attached",
67+
this.field.attribute,
68+
this.field.idKey
69+
];
6170
62-
if( this.resourceId )
63-
{
64-
Nova.request( baseUrl + this.resourceName + '/' + this.resourceId + '/attached/' + this.field.attribute )
65-
.then( ( data ) =>
66-
{
67-
this.selectedValues = data.data || [];
68-
} );
69-
}
71+
Nova.request( url.join( "/" ) )
72+
.then( ( data ) =>
73+
{
74+
if(!this.field.multiple)
75+
{
76+
this.selectedValues = data.data || undefined;
77+
}
78+
else
79+
{
80+
this.selectedValues = data.data || [];
81+
}
82+
} );
83+
}
7084
},
7185
fill( formData )
7286
{

resources/js/components/FormField.vue

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default {
3939
data()
4040
{
4141
return {
42-
selectedValues: [],
42+
selectedValues: null,
4343
};
4444
},
4545
methods: {
@@ -63,12 +63,38 @@ export default {
6363
6464
if( this.resourceId )
6565
{
66-
Nova.request( baseUrl + this.resourceName + '/' + this.resourceId + '/attached/' + this.field.attribute )
67-
.then( ( data ) =>
68-
{
69-
this.selectedValues = data.data || [];
66+
const url = [
67+
baseUrl + this.resourceName,
68+
this.resourceId,
69+
'attached',
70+
this.field.attribute,
71+
this.field.idKey
72+
];
73+
74+
Nova.request( url.join('/') )
75+
.then( ( data ) => {
76+
77+
if(!this.field.multiple)
78+
{
79+
this.selectedValues = data.data || undefined;
80+
}
81+
else
82+
{
83+
this.selectedValues = data.data || [];
84+
}
7085
} );
7186
}
87+
else
88+
{
89+
if(!this.field.multiple)
90+
{
91+
this.selectedValues = undefined;
92+
}
93+
else
94+
{
95+
this.selectedValues = [];
96+
}
97+
}
7298
},
7399
fill( formData )
74100
{
@@ -81,7 +107,7 @@ export default {
81107
},
82108
firstError: function() {
83109
return this.errors.errors[this.field.attribute][0]
84-
},
110+
}
85111
}
86112
}
87113
</script>

routes/api.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<?php
22

3-
Route::get('/{resource}/{resourceId}/attached/{relationship}', 'PhoenixLib\NovaNestedTreeAttachMany\Http\Controllers\NestedTreeController@attached');
3+
Route::get('/{resource}/{resourceId}/attached/{relationship}/{idKey}', 'PhoenixLib\NovaNestedTreeAttachMany\Http\Controllers\NestedTreeController@attached');
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
namespace PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation\Handlers;
3+
4+
use DomainException;
5+
6+
class BelongsToHandler implements RelationHandler
7+
{
8+
public function relation(): string
9+
{
10+
return 'Illuminate\Database\Eloquent\Relations\BelongsTo';
11+
}
12+
13+
public function attach( $model, $relationship, $value): void
14+
{
15+
if(is_array($value))
16+
{
17+
throw new DomainException('Can`t use BelongsTo relation with multiple select.');
18+
}
19+
20+
if(intval($value) > 0)
21+
{
22+
$relationModel = $model->{$relationship}()->getModel();
23+
24+
$model->{$relationship}()->associate($relationModel->find($value));
25+
}
26+
else
27+
{
28+
$model->{$relationship}()->dissociate();
29+
}
30+
31+
$model->saveQuietly();
32+
}
33+
34+
public function retrieve($model, $relationship, $idKey)
35+
{
36+
return $model->{$relationship} ? $model->{$relationship}->{$idKey}: null;
37+
}
38+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
namespace PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation\Handlers;
3+
4+
class BelongsToManyHandler implements RelationHandler
5+
{
6+
public function relation(): string
7+
{
8+
return 'Illuminate\Database\Eloquent\Relations\BelongsToMany';
9+
}
10+
11+
public function attach( $model, $relationship, $values): void
12+
{
13+
$model->{$relationship}()->sync($values);
14+
}
15+
16+
public function retrieve($model, $relationship, $idKey)
17+
{
18+
return $model->{$relationship}->pluck($idKey)->all();
19+
}
20+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
namespace PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation\Handlers;
3+
4+
class HasManyHandler implements RelationHandler
5+
{
6+
private $updated = false;
7+
8+
public function relation(): string
9+
{
10+
return 'Illuminate\Database\Eloquent\Relations\HasMany';
11+
}
12+
13+
public function attach( $model, $relationship, $values): void
14+
{
15+
$dispatcher = $model->getEventDispatcher();
16+
17+
$model->unsetEventDispatcher();
18+
19+
20+
21+
$relationModel = $model->{$relationship}()->getModel();
22+
23+
$models = $relationModel->find($values);
24+
25+
$models->each(function ( $children ) use ( $model ){
26+
27+
if(!$children->is($model))
28+
{
29+
if(!$model->ancestors->contains($children))
30+
{
31+
$this->updated = true;
32+
33+
$children->parent()->associate($model);
34+
$children->save();
35+
}
36+
}
37+
38+
});
39+
40+
41+
42+
foreach($model->{$relationship} as $children )
43+
{
44+
if(!$models->contains($children))
45+
{
46+
$this->updated = true;
47+
48+
$children->parent()->dissociate();
49+
$children->save();
50+
}
51+
}
52+
53+
54+
55+
if($this->updated)
56+
{
57+
$model->fixTree();
58+
}
59+
60+
61+
62+
$model->setEventDispatcher($dispatcher);
63+
}
64+
65+
public function retrieve($model, $relationship, $idKey)
66+
{
67+
return $model->{$relationship}->pluck($idKey)->all();
68+
}
69+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation\Handlers;
3+
4+
interface RelationHandler
5+
{
6+
public function relation(): string;
7+
8+
public function attach( $model, $relationship, $values): void;
9+
10+
public function retrieve($model, $relationship, $idKey);
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation;
4+
5+
use Illuminate\Support\Collection;
6+
use PhoenixLib\NovaNestedTreeAttachMany\Domain\Relation\Handlers\RelationHandler;
7+
8+
interface RelationHandlerFactory
9+
{
10+
public function make($relation): RelationHandler;
11+
12+
public function register( RelationHandler $handler ): void;
13+
14+
public function unregister( RelationHandler $handler ): void;
15+
16+
public function registeredHandlers(): Collection;
17+
18+
public function unregisterAll(): void;
19+
}

0 commit comments

Comments
 (0)