Skip to content

Commit 741d5cf

Browse files
Merge pull request #8 from WatheqAlshowaiter/feat/exclude-model-default-attributes
Feat/exclude model default attributes
2 parents 9796180 + bc2bdeb commit 741d5cf

File tree

7 files changed

+95
-3
lines changed

7 files changed

+95
-3
lines changed

.github/workflows/fix-php-code-style-issues.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
paths:
66
- "**.php"
7+
pull_request:
78
workflow_dispatch:
89

910
permissions:

.github/workflows/tests-for-databases.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
- "phpunit.xml.dist"
1010
- "composer.json"
1111
- "composer.lock"
12+
pull_request:
1213
workflow_dispatch:
1314

1415
jobs:

.github/workflows/tests-for-laravel-versions.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
- "phpunit.xml.dist"
1010
- "composer.json"
1111
- "composer.lock"
12+
pull_request:
1213
workflow_dispatch:
1314

1415
jobs:

src/RequiredFields.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ trait RequiredFields
1111
/**
1212
* Get only required fields for the model that
1313
* need to be added while creating a new record in the database.
14-
* So, we ignore auto_increment, primary keys, nullable and default fields.
14+
* So, we ignore auto_increment, primary keys, nullable
15+
* and default fields (either from database or application).
1516
*
16-
* @return array
17+
* @return array<string>
1718
*/
1819
public static function getRequiredFields(
1920
$withNullables = false,
@@ -28,6 +29,8 @@ public static function getRequiredFields(
2829
);
2930
}
3031

32+
$modelDefaultAttributes = self::getModelDefaultAttributes();
33+
3134
$primaryIndex = collect(Schema::getIndexes((new self)->getTable()))
3235
->filter(function ($index) {
3336
return $index['primary'];
@@ -50,6 +53,9 @@ public static function getRequiredFields(
5053
$column['default'] != null && ! $withDefaults ||
5154
(in_array($column['name'], $primaryIndex));
5255
})
56+
->reject(function ($column) use ($modelDefaultAttributes, $withDefaults) {
57+
return in_array($column['name'], $modelDefaultAttributes) && ! $withDefaults;
58+
})
5359
->pluck('name')
5460
->when($withPrimaryKey, function ($collection) use ($primaryIndex) {
5561
return $collection->prepend(...$primaryIndex);
@@ -105,6 +111,7 @@ protected static function getRequiredFieldsForSqlite(
105111
$withPrimaryKey = false
106112
) {
107113
$table = self::getTableFromThisModel();
114+
$modelDefaultAttributes = self::getModelDefaultAttributes();
108115

109116
$queryResult = DB::select(/** @lang SQLite */ "PRAGMA table_info($table)");
110117

@@ -117,8 +124,12 @@ protected static function getRequiredFieldsForSqlite(
117124
|| $column['dflt_value'] != null && ! $withDefaults
118125
|| ! $column['notnull'] && ! $withNullables;
119126
})
127+
->reject(function ($column) use ($modelDefaultAttributes, $withDefaults) {
128+
return in_array($column['name'], $modelDefaultAttributes) && ! $withDefaults;
129+
})
120130
->pluck('name')
121131
->toArray();
132+
122133
}
123134

124135
protected static function getRequiredFieldsForMysqlAndMariaDb(
@@ -127,6 +138,7 @@ protected static function getRequiredFieldsForMysqlAndMariaDb(
127138
$withPrimaryKey = false
128139
) {
129140
$table = self::getTableFromThisModel();
141+
$modelDefaultAttributes = self::getModelDefaultAttributes();
130142

131143
$queryResult = DB::select(
132144
/** @lang SQLite */ "
@@ -162,6 +174,9 @@ protected static function getRequiredFieldsForMysqlAndMariaDb(
162174
|| $column['default'] != null && ! $withDefaults
163175
|| $column['nullable'] && ! $withNullables;
164176
})
177+
->reject(function ($column) use ($modelDefaultAttributes, $withDefaults) {
178+
return in_array($column['name'], $modelDefaultAttributes) && ! $withDefaults;
179+
})
165180
->pluck('name')
166181
->toArray();
167182
}
@@ -172,6 +187,7 @@ protected static function getRequiredFieldsForPostgres(
172187
$withPrimaryKey = false
173188
) {
174189
$table = self::getTableFromThisModel();
190+
$modelDefaultAttributes = self::getModelDefaultAttributes();
175191

176192
$primaryIndex = DB::select(/** @lang PostgreSQL */ "
177193
SELECT
@@ -234,6 +250,9 @@ protected static function getRequiredFieldsForPostgres(
234250
($column['nullable'] == 'YES' && ! $withNullables) ||
235251
(in_array($column['name'], $primaryIndex));
236252
})
253+
->reject(function ($column) use ($modelDefaultAttributes, $withDefaults) {
254+
return in_array($column['name'], $modelDefaultAttributes) && ! $withDefaults;
255+
})
237256
->pluck('name')
238257
->when($withPrimaryKey, function ($collection) use ($primaryIndex) {
239258
return $collection->prepend(...$primaryIndex);
@@ -248,6 +267,7 @@ protected static function getRequiredFieldsForSqlServer(
248267
$withPrimaryKey = false
249268
) {
250269
$table = self::getTableFromThisModel();
270+
$modelDefaultAttributes = self::getModelDefaultAttributes();
251271

252272
$primaryIndex = DB::select(/** @lang TSQL */ '
253273
SELECT
@@ -295,6 +315,9 @@ protected static function getRequiredFieldsForSqlServer(
295315
|| $column['nullable'] && ! $withNullables
296316
|| (in_array($column['name'], $primaryIndex) && ! $withPrimaryKey);
297317
})
318+
->reject(function ($column) use ($modelDefaultAttributes, $withDefaults) {
319+
return in_array($column['name'], $modelDefaultAttributes) && ! $withDefaults;
320+
})
298321
->pluck('name')
299322
->toArray();
300323
}
@@ -309,6 +332,14 @@ protected static function getTableFromThisModel()
309332
return str_replace('.', '__', $table);
310333
}
311334

335+
/**
336+
* @return array<string>
337+
*/
338+
protected static function getModelDefaultAttributes()
339+
{
340+
return array_keys((new self)->getAttributes());
341+
}
342+
312343
public static function getRequiredFieldsWithNullables()
313344
{
314345
return self::getRequiredFields($withNullables = true, $withDefaults = false, $withPrimaryKey = false);

tests/Models/Brother.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace WatheqAlshowaiter\ModelRequiredFields\Tests\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use WatheqAlshowaiter\ModelRequiredFields\RequiredFields;
7+
8+
class Brother extends Model
9+
{
10+
use RequiredFields;
11+
12+
protected $attributes = [
13+
'name' => 'default-user', // default
14+
'another' => '', // non-valid default
15+
'non-existed-field' => 'some-random-value', // non-existed field in the database
16+
];
17+
}

tests/RequiredFieldsTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<?php
22

3+
namespace WatheqAlshowaiter\ModelRequiredFields\Tests;
4+
35
use Illuminate\Foundation\Testing\RefreshDatabase;
6+
use WatheqAlshowaiter\ModelRequiredFields\Tests\Models\Brother;
47
use WatheqAlshowaiter\ModelRequiredFields\Tests\Models\Father;
58
use WatheqAlshowaiter\ModelRequiredFields\Tests\Models\Mother;
69
use WatheqAlshowaiter\ModelRequiredFields\Tests\Models\Son;
7-
use WatheqAlshowaiter\ModelRequiredFields\Tests\TestCase;
810

911
class RequiredFieldsTest extends TestCase
1012
{
@@ -246,4 +248,22 @@ public function test_get_required_fields_for_son_model_for_older_versions()
246248
'father_id',
247249
], Son::getRequiredFieldsForOlderVersions());
248250
}
251+
252+
public function test_get_required_fields_excluding_default_model_attributes()
253+
{
254+
$this->assertEquals([
255+
'email',
256+
], Brother::getRequiredFields());
257+
}
258+
259+
public function test_get_required_fields_with_applications_defaults()
260+
{
261+
$expected = [
262+
'email',
263+
'name',
264+
];
265+
266+
$this->assertEquals($expected, Brother::getRequiredFieldsWithDefaults());
267+
$this->assertEquals($expected, Brother::getRequiredFields($withNullables = false, $withDefaults = true));
268+
}
249269
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateBrothersTable extends Migration
8+
{
9+
public function up(): void
10+
{
11+
Schema::create('brothers', function (Blueprint $table) {
12+
$table->string('email'); // required
13+
$table->string('name'); // default => ignored because it has the default value in the model $attributes
14+
});
15+
}
16+
17+
public function down(): void
18+
{
19+
Schema::dropIfExists('brothers');
20+
}
21+
}

0 commit comments

Comments
 (0)