Skip to content

Commit 6aceec3

Browse files
authored
Merge pull request #4554 from Laravel-Backpack/pr/4553
[bug] Scoped HasMany relations - incorrect delete entries
2 parents 23546ed + 1ba519a commit 6aceec3

File tree

6 files changed

+205
-5
lines changed

6 files changed

+205
-5
lines changed

src/app/Library/CrudPanel/Traits/Create.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,10 @@ private function attachManyRelation($item, $relation, $relationDetails, $relatio
222222
$relationForeignKey = $relation->getForeignKeyName();
223223
$relationLocalKey = $relation->getLocalKeyName();
224224

225-
if ($relationValues === null) {
225+
if (empty($relationValues)) {
226226
// the developer cleared the selection
227227
// we gonna clear all related values by setting up the value to the fallback id, to null or delete.
228-
$removedEntries = $modelInstance->where($relationForeignKey, $item->{$relationLocalKey});
229-
230-
return $this->handleManyRelationItemRemoval($modelInstance, $removedEntries, $relationDetails, $relationForeignKey);
228+
return $this->handleManyRelationItemRemoval($modelInstance, $relation, $relationDetails, $relationForeignKey);
231229
}
232230
// we add the new values into the relation, if it is HasMany we only update the foreign_key,
233231
// otherwise (it's a MorphMany) we need to update the morphs keys too

src/app/Library/CrudPanel/Traits/Relationships.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ private static function getPivotFieldStructure($field)
298298
$pivotSelectorField['minimum_input_length'] = 2;
299299
$pivotSelectorField['delay'] = 500;
300300
$pivotSelectorField['placeholder'] = trans('backpack::crud.select_entry');
301-
$pivotSelectorField['label'] = \Str::of($field['name'])->singular()->ucfirst();
301+
$pivotSelectorField['label'] = Str::of($field['name'])->singular()->ucfirst();
302302
$pivotSelectorField['validationRules'] = 'required';
303303
$pivotSelectorField['validationMessages'] = [
304304
'required' => trans('backpack::crud.pivot_selector_required_validation_message'),

tests/Unit/CrudPanel/CrudPanelCreateTest.php

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,126 @@ public function testHasManySelectableRelationshipRemoveAllRelations()
990990
$this->assertCount(2, $planets);
991991
}
992992

993+
public function testHasManyWithRelationScoped()
994+
{
995+
$this->crudPanel->setModel(User::class);
996+
$this->crudPanel->addFields($this->userInputFieldsNoRelationships, 'both');
997+
$this->crudPanel->addField([
998+
'name' => 'incomes',
999+
'subfields' => [
1000+
[
1001+
'name' => 'label',
1002+
'type' => 'text',
1003+
],
1004+
[
1005+
'name' => 'type',
1006+
'type' => 'hidden',
1007+
'value' => 'income',
1008+
],
1009+
[
1010+
'name' => 'amount',
1011+
'type' => 'number',
1012+
],
1013+
],
1014+
], 'both');
1015+
$this->crudPanel->addField([
1016+
'name' => 'expenses',
1017+
'subfields' => [
1018+
[
1019+
'name' => 'label',
1020+
'type' => 'text',
1021+
],
1022+
[
1023+
'name' => 'type',
1024+
'type' => 'hidden',
1025+
'value' => 'expense',
1026+
],
1027+
[
1028+
'name' => 'amount',
1029+
'type' => 'number',
1030+
],
1031+
],
1032+
], 'both');
1033+
1034+
$faker = Factory::create();
1035+
$inputData = [
1036+
'name' => $faker->name,
1037+
'email' => $faker->safeEmail,
1038+
'password' => bcrypt($faker->password()),
1039+
'remember_token' => null,
1040+
'incomes' => [
1041+
[
1042+
'label' => $faker->name,
1043+
'amount' => 33,
1044+
'type' => 'income',
1045+
],
1046+
[
1047+
'label' => $faker->name,
1048+
'amount' => 22,
1049+
'type' => 'income',
1050+
],
1051+
],
1052+
'expenses' => [
1053+
[
1054+
'label' => $faker->name,
1055+
'amount' => 44,
1056+
'type' => 'expense',
1057+
],
1058+
[
1059+
'label' => $faker->name,
1060+
'amount' => 10,
1061+
'type' => 'expense',
1062+
],
1063+
],
1064+
];
1065+
$entry = $this->crudPanel->create($inputData);
1066+
1067+
$firstExpense = $entry->expenses->first();
1068+
$firstIncome = $entry->incomes->first();
1069+
$this->assertCount(2, $entry->expenses);
1070+
$this->assertCount(2, $entry->incomes);
1071+
$this->assertEquals(44, $entry->expenses->first()->amount);
1072+
$this->assertEquals(33, $entry->incomes->first()->amount);
1073+
1074+
$inputData['incomes'] = [
1075+
[
1076+
'id' => 2,
1077+
'label' => $faker->name,
1078+
'amount' => 222,
1079+
'type' => 'income',
1080+
],
1081+
];
1082+
$inputData['expenses'] = [
1083+
[
1084+
'id' => 3,
1085+
'label' => $faker->name,
1086+
'amount' => 44,
1087+
'type' => 'expense',
1088+
],
1089+
[
1090+
'id' => 4,
1091+
'label' => $faker->name,
1092+
'amount' => 10,
1093+
'type' => 'expense',
1094+
],
1095+
];
1096+
$this->crudPanel->update($entry->id, $inputData);
1097+
1098+
$freshIncomes = $entry->fresh()->incomes;
1099+
$freshExpenses = $entry->fresh()->expenses;
1100+
$this->assertCount(2, $freshExpenses);
1101+
$this->assertCount(1, $freshIncomes);
1102+
$this->assertEquals(2, $freshIncomes->first()->id);
1103+
1104+
$inputData['expenses'] = [];
1105+
$this->crudPanel->update($entry->id, $inputData);
1106+
1107+
$freshIncomes = $entry->fresh()->incomes;
1108+
$freshExpenses = $entry->fresh()->expenses;
1109+
$this->assertCount(0, $freshExpenses);
1110+
$this->assertCount(1, $freshIncomes);
1111+
}
1112+
9931113
public function testHasManySelectableRelationshipWithFallbackId()
9941114
{
9951115
$this->crudPanel->setModel(User::class);

tests/Unit/Models/Transaction.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Backpack\CRUD\Tests\Unit\Models;
4+
5+
use Backpack\CRUD\app\Models\Traits\CrudTrait;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class Transaction extends Model
9+
{
10+
use CrudTrait;
11+
12+
/*
13+
|--------------------------------------------------------------------------
14+
| GLOBAL VARIABLES
15+
|--------------------------------------------------------------------------
16+
*/
17+
18+
protected $table = 'transactions';
19+
protected $primaryKey = 'id';
20+
public $timestamps = false;
21+
protected $fillable = ['type', 'amount', 'user_id', 'label'];
22+
// protected $hidden = [];
23+
// protected $dates = [];
24+
25+
/*
26+
|--------------------------------------------------------------------------
27+
| FUNCTIONS
28+
|--------------------------------------------------------------------------
29+
*/
30+
31+
public function scopeOfType($query, $type)
32+
{
33+
return $query->where('type', $type);
34+
}
35+
36+
/*
37+
|--------------------------------------------------------------------------
38+
| RELATIONS
39+
|--------------------------------------------------------------------------
40+
*/
41+
42+
public function user()
43+
{
44+
return $this->belongsTo('Backpack\CRUD\Tests\Unit\Models\User');
45+
}
46+
47+
/*
48+
|--------------------------------------------------------------------------
49+
| SCOPES
50+
|--------------------------------------------------------------------------
51+
*/
52+
53+
/*
54+
|--------------------------------------------------------------------------
55+
| ACCESORS
56+
|--------------------------------------------------------------------------
57+
*/
58+
59+
/*
60+
|--------------------------------------------------------------------------
61+
| MUTATORS
62+
|--------------------------------------------------------------------------
63+
*/
64+
}

tests/Unit/Models/User.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,14 @@ public function bang()
9090
{
9191
return $this->belongsTo('Backpack\CRUD\Tests\Unit\Models\Bang', 'bang_relation_field');
9292
}
93+
94+
public function incomes()
95+
{
96+
return $this->hasMany('Backpack\CRUD\Tests\Unit\Models\Transaction')->ofType('income');
97+
}
98+
99+
public function expenses()
100+
{
101+
return $this->hasMany('Backpack\CRUD\Tests\Unit\Models\Transaction')->ofType('expense');
102+
}
93103
}

tests/config/database/migrations/2020_03_31_114745_create_pivotable_relations_tables.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public function up()
7979
$table->string('title')->nullable();
8080
});
8181

82+
Schema::create('transactions', function (Blueprint $table) {
83+
$table->bigIncrements('id')->unique();
84+
$table->bigInteger('user_id');
85+
$table->string('label')->nullable();
86+
$table->bigInteger('amount');
87+
$table->string('type');
88+
});
89+
8290
Schema::create('planets_non_nullable', function (Blueprint $table) {
8391
$table->bigIncrements('id');
8492
$table->bigInteger('user_id');

0 commit comments

Comments
 (0)