Skip to content

Commit 558cb14

Browse files
josip-miloticJosip MilotićStyleCIBot
authored
Remove unique name constraint (#87)
* Removed db unique name constraint for custom fields * Apply fixes from StyleCI * Added check event model * Minor cleanup * Changed validation to account for soft deletes in case they are used * Apply fixes from StyleCI * Fix --------- Co-authored-by: Josip Milotić <[email protected]> Co-authored-by: StyleCI Bot <[email protected]>
1 parent 0406263 commit 558cb14

11 files changed

+134
-6
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('custom_fields', function (Blueprint $table) {
17+
$table->dropIndex('cf_name');
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('custom_fields', function (Blueprint $table) {
29+
$table->unique('name', 'cf_name');
30+
});
31+
}
32+
};

src/App/Http/Controllers/PlainCustomFieldController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function __construct(CustomField $customField)
2727
* Display a listing of the resource.
2828
*
2929
* @path plain_type string One of the plain types (string, text, integer, float, date, boolean)
30+
*
3031
* @multiple true
3132
*
3233
* @param string|null $type
@@ -41,6 +42,7 @@ public function index(string $type = null): JsonResponse
4142
* Store a newly created resource in storage.
4243
*
4344
* @path plain_type string One of the plain types (string, text, integer, float, date, boolean)
45+
*
4446
* @except selectable_type selectable_id
4547
*
4648
* @param PlainCustomFieldRequest $request

src/App/Http/Controllers/RemoteCustomFieldController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
/**
1818
* @group Remote Custom Fields
19+
*
1920
* @model CustomField
2021
*/
2122
class RemoteCustomFieldController extends Controller
@@ -47,6 +48,7 @@ public function index(): JsonResponse
4748
* Store a newly created resource in storage.
4849
*
4950
* @except selectable_type selectable_id
51+
*
5052
* @append remote RemoteType
5153
*
5254
* @param RemoteCustomFieldRequest $request
@@ -58,7 +60,6 @@ public function store(RemoteCustomFieldRequest $request): JsonResponse
5860

5961
/** @var CustomField $customField */
6062
$customField = DB::transaction(function () use ($data) {
61-
6263
// Force casting remote types to string unless we decide on different implementation.
6364
$plainTypeId = $this->plainType::query()->where('name', 'string')->firstOrFail()->id;
6465

src/App/Http/Controllers/SelectionCustomFieldController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public function index(): JsonResponse
4545
* Store a newly created resource in storage.
4646
*
4747
* @path plain_type string One of the plain types (string, text, integer, float, date, boolean)
48+
*
4849
* @except selectable_type selectable_id
50+
*
4951
* @append selection SelectionType
5052
* @append values SelectionValue
5153
*

src/App/Http/Requests/CustomFieldCreateRequest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace Asseco\CustomFields\App\Http\Requests;
66

7+
use Asseco\CustomFields\App\Contracts\CustomField as CustomFieldContract;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
79
use Illuminate\Foundation\Http\FormRequest;
10+
use Illuminate\Validation\Rule;
811

912
class CustomFieldCreateRequest extends FormRequest
1013
{
@@ -26,7 +29,14 @@ public function authorize()
2629
public function rules()
2730
{
2831
return [
29-
'name' => 'required|string|regex:/^[^\s]*$/i|unique:custom_fields,name' . ($this->custom_field ? ',' . $this->custom_field->id : null),
32+
'name' => [
33+
'required',
34+
'string',
35+
'regex:/^[^\s]*$/i',
36+
Rule::unique('custom_fields')->ignore($this->custom_field)->where(function ($query) {
37+
return $this->usesSoftDelete() ? $query->whereNull('deleted_at') : $query;
38+
}),
39+
],
3040
'label' => 'required|string|max:255',
3141
'placeholder' => 'nullable|string',
3242
'selectable_type' => 'required',
@@ -51,4 +61,9 @@ public function messages()
5161
'name.regex' => 'Custom field name must not contain spaces.',
5262
];
5363
}
64+
65+
private function usesSoftDelete(): bool
66+
{
67+
return in_array(SoftDeletes::class, class_uses_recursive(app(CustomFieldContract::class)));
68+
}
5469
}

src/App/Http/Requests/CustomFieldUpdateRequest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
namespace Asseco\CustomFields\App\Http\Requests;
66

7+
use Asseco\CustomFields\App\Contracts\CustomField as CustomFieldContract;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
79
use Illuminate\Foundation\Http\FormRequest;
810
use Illuminate\Support\Arr;
11+
use Illuminate\Validation\Rule;
912

1013
class CustomFieldUpdateRequest extends FormRequest
1114
{
@@ -32,7 +35,14 @@ public function authorize()
3235
public function rules()
3336
{
3437
$rules = [
35-
'name' => 'sometimes|string|regex:/^[^\s]*$/i|unique:custom_fields,name' . ($this->custom_field ? ',' . $this->custom_field->id : null),
38+
'name' => [
39+
'required',
40+
'string',
41+
'regex:/^[^\s]*$/i',
42+
Rule::unique('custom_fields')->ignore($this->custom_field)->where(function ($query) {
43+
return $this->usesSoftDelete() ? $query->whereNull('deleted_at') : $query;
44+
}),
45+
],
3646
'label' => 'sometimes|string|max:255',
3747
'placeholder' => 'nullable|string',
3848
'required' => 'boolean',
@@ -56,4 +66,9 @@ public function messages()
5666
'name.regex' => 'Custom field name must not contain spaces.',
5767
];
5868
}
69+
70+
private function usesSoftDelete(): bool
71+
{
72+
return in_array(SoftDeletes::class, class_uses_recursive(app(CustomFieldContract::class)));
73+
}
5974
}

src/App/Http/Requests/PlainCustomFieldRequest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace Asseco\CustomFields\App\Http\Requests;
66

7+
use Asseco\CustomFields\App\Contracts\CustomField as CustomFieldContract;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
79
use Illuminate\Foundation\Http\FormRequest;
10+
use Illuminate\Validation\Rule;
811

912
class PlainCustomFieldRequest extends FormRequest
1013
{
@@ -26,7 +29,14 @@ public function authorize()
2629
public function rules()
2730
{
2831
return [
29-
'name' => 'required|string|regex:/^[^\s]*$/i|unique:custom_fields,name' . ($this->custom_field ? ',' . $this->custom_field->id : null),
32+
'name' => [
33+
'required',
34+
'string',
35+
'regex:/^[^\s]*$/i',
36+
Rule::unique('custom_fields')->ignore($this->custom_field)->where(function ($query) {
37+
return $this->usesSoftDelete() ? $query->whereNull('deleted_at') : $query;
38+
}),
39+
],
3040
'label' => 'required|string|max:255',
3141
'placeholder' => 'nullable|string',
3242
'model' => 'required|string',
@@ -48,4 +58,9 @@ public function messages()
4858
'name.regex' => 'Custom field name must not contain spaces.',
4959
];
5060
}
61+
62+
private function usesSoftDelete(): bool
63+
{
64+
return in_array(SoftDeletes::class, class_uses_recursive(app(CustomFieldContract::class)));
65+
}
5166
}

src/App/Http/Requests/RemoteCustomFieldRequest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace Asseco\CustomFields\App\Http\Requests;
66

7+
use Asseco\CustomFields\App\Contracts\CustomField as CustomFieldContract;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
79
use Illuminate\Foundation\Http\FormRequest;
10+
use Illuminate\Validation\Rule;
811

912
class RemoteCustomFieldRequest extends FormRequest
1013
{
@@ -26,7 +29,14 @@ public function authorize()
2629
public function rules()
2730
{
2831
return [
29-
'name' => 'required|string|regex:/^[^\s]*$/i|unique:custom_fields,name' . ($this->custom_field ? ',' . $this->custom_field->id : null),
32+
'name' => [
33+
'required',
34+
'string',
35+
'regex:/^[^\s]*$/i',
36+
Rule::unique('custom_fields')->ignore($this->custom_field)->where(function ($query) {
37+
return $this->usesSoftDelete() ? $query->whereNull('deleted_at') : $query;
38+
}),
39+
],
3040
'label' => 'required|string|max:255',
3141
'placeholder' => 'nullable|string',
3242
'model' => 'required|string',
@@ -56,4 +66,9 @@ public function messages()
5666
'name.regex' => 'Custom field name must not contain spaces.',
5767
];
5868
}
69+
70+
private function usesSoftDelete(): bool
71+
{
72+
return in_array(SoftDeletes::class, class_uses_recursive(app(CustomFieldContract::class)));
73+
}
5974
}

src/App/Http/Requests/SelectionCustomFieldRequest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace Asseco\CustomFields\App\Http\Requests;
66

7+
use Asseco\CustomFields\App\Contracts\CustomField as CustomFieldContract;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
79
use Illuminate\Foundation\Http\FormRequest;
10+
use Illuminate\Validation\Rule;
811

912
class SelectionCustomFieldRequest extends FormRequest
1013
{
@@ -26,7 +29,14 @@ public function authorize()
2629
public function rules()
2730
{
2831
return [
29-
'name' => 'required|string|regex:/^[^\s]*$/i|unique:custom_fields,name' . ($this->custom_field ? ',' . $this->custom_field->id : null),
32+
'name' => [
33+
'required',
34+
'string',
35+
'regex:/^[^\s]*$/i',
36+
Rule::unique('custom_fields')->ignore($this->custom_field)->where(function ($query) {
37+
return $this->usesSoftDelete() ? $query->whereNull('deleted_at') : $query;
38+
}),
39+
],
3040
'label' => 'required|string|max:255',
3141
'placeholder' => 'nullable|string',
3242
'model' => 'required|string',
@@ -54,4 +64,9 @@ public function messages()
5464
'name.regex' => 'Custom field name must not contain spaces.',
5565
];
5666
}
67+
68+
private function usesSoftDelete(): bool
69+
{
70+
return in_array(SoftDeletes::class, class_uses_recursive(app(CustomFieldContract::class)));
71+
}
5772
}

src/App/Models/CustomField.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ protected static function booted()
6565
$customField->parent()->delete();
6666
$customField->children()->delete();
6767
});
68+
69+
static::saving(function (self $customField) {
70+
if ($customField->isDirty('name') && $customField->exists()) {
71+
throw new Exception("Custom field with the name $customField->name already exists.");
72+
}
73+
});
6874
}
6975

7076
public function selectable(): MorphTo
@@ -185,4 +191,11 @@ public function shortFormat($value): array
185191
'value' => $value,
186192
]];
187193
}
194+
195+
protected function exists(): bool
196+
{
197+
return app(CustomFieldContract::class)::query()
198+
->where('name', $this->name)
199+
->exists();
200+
}
188201
}

0 commit comments

Comments
 (0)