Giter Club home page Giter Club logo

laravel-schema-rules's Introduction

Laravel Schema Rules

Latest Version on Packagist Tests Check & fix styling License Total Downloads

Automatically generate basic Laravel validation rules based on your database table schema! Use these as a starting point to fine-tune and optimize your validation rules as needed.

Here you can use the web version, if you like: https://validationforlaravel.com

Installation

You can install the package via composer:

composer require laracraft-tech/laravel-schema-rules --dev

Then publish the config file with:

php artisan vendor:publish --tag="schema-rules-config"

ToC

Usage

Let's say you've migrated this fictional table:

Schema::create('persons', function (Blueprint $table) {
    $table->id();
    $table->string('first_name', 100);
    $table->string('last_name', 100);
    $table->string('email');
    $table->foreignId('address_id')->constrained();
    $table->text('bio')->nullable();
    $table->enum('gender', ['m', 'f', 'd']);
    $table->date('birth');
    $table->year('graduated');
    $table->float('body_size');
    $table->unsignedTinyInteger('children_count')->nullable();
    $table->integer('account_balance');
    $table->unsignedInteger('net_income');
    $table->boolean('send_newsletter')->nullable();
});

Generate rules for a whole table

Now if you run:

php artisan schema:generate-rules persons

You'll get:

Schema-based validation rules for table "persons" have been generated!
Copy & paste these to your controller validation or form request or where ever your validation takes place:
[
    'first_name' => ['required', 'string', 'min:1', 'max:100'],
    'last_name' => ['required', 'string', 'min:1', 'max:100'],
    'email' => ['required', 'string', 'min:1', 'max:255'],
    'address_id' => ['required', 'exists:addresses,id'],
    'bio' => ['nullable', 'string', 'min:1'],
    'gender' => ['required', 'string', 'in:m,f,d'],
    'birth' => ['required', 'date'],
    'graduated' => ['required', 'integer', 'min:1901', 'max:2155'],
    'body_size' => ['required', 'numeric'],
    'children_count' => ['nullable', 'integer', 'min:0', 'max:255'],
    'account_balance' => ['required', 'integer', 'min:-2147483648', 'max:2147483647'],
    'net_income' => ['required', 'integer', 'min:0', 'max:4294967295'],
    'send_newsletter' => ['nullable', 'boolean']
]

As you may have noticed the float-column body_size, just gets generated to ['required', 'numeric']. Proper rules for float, decimal and double, are not yet implemented!

Generate rules for specific columns

You can also explicitly specify the columns:

php artisan schema:generate-rules persons --columns first_name,last_name,email

Which gives you:

Schema-based validation rules for table "persons" have been generated!
Copy & paste these to your controller validation or form request or where ever your validation takes place:
[
    'first_name' => ['required', 'string', 'min:1', 'max:100'],
    'last_name' => ['required', 'string', 'min:1', 'max:100'],
    'email' => ['required', 'string', 'min:1', 'max:255']
]

Generate Form Request Class

Optionally, you can add a --create-request or -c flag, which will create a form request class with the generated rules for you!

# creates app/Http/Requests/StorePersonRequest.php (store request is the default)
php artisan schema:generate-rules persons --create-request

# creates/overwrites app/Http/Requests/StorePersonRequest.php
php artisan schema:generate-rules persons --create-request --force

# creates app/Http/Requests/UpdatePersonRequest.php
php artisan schema:generate-rules persons --create-request --file UpdatePersonRequest

# creates app/Http/Requests/Api/V1/StorePersonRequest.php
php artisan schema:generate-rules persons --create-request --file Api\\V1\\StorePersonRequest

# creates/overwrites app/Http/Requests/Api/V1/StorePersonRequest.php (using shortcuts)
php artisan schema:generate-rules persons -cf --file Api\\V1\\StorePersonRequest

Always skip columns

To always skip columns add it in the config file, under skip_columns parameter.

'skip_columns' => ['whatever', 'some_other_column'],

Supported Drivers

Currently, the supported database drivers are MySQL, PostgreSQL, and SQLite.

Please note, since each driver supports different data types and range specifications, the validation rules generated by this package may vary depending on the database driver you are using.

Testing

Before running tests, you need to set up a local MySQL database named laravel_schema_rules and update its username and password in the phpunit.xml.dist file.

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-schema-rules's People

Contributors

dependabot[bot] avatar dreammonkey avatar giagara avatar github-actions[bot] avatar mathieutu avatar sairahcaz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-schema-rules's Issues

Implicit rules instead of scaffolding on the fly

It would be nice if I could do something like this:

public rules()
{
    return [
        'email' => 'email:rfc,dns',
    ] + \LaracraftTech\LaravelSchemaRules\Resolvers\BaseSchemaRulesResolver::generate();
}

or do you consider this out of scope?

I know, the above code is just pseudocode. There would have to be a merge() method to prevent the keys from overwriting each other.

Provide database migration for running tests.

๐Ÿ‘‹๐Ÿฝ hi there !

Thanks for this cool package !
I have written something similar in the past, but your package is much more elaborated ๐Ÿ™Œ๐Ÿฝ

I would like to tinker a bit and maybe contribute some small things.
But it seems I'm unable to successfully run the tests.
I see your migration test file is not included in the source code, is there any reason for this ?

 public function getEnvironmentSetUp($app)
    {
        config()->set('database.default', 'testing');


        $migration = include __DIR__ . '/../database/migrations/create_laravel-dynamic-model_table.php.stub';
        $migration->up();
    }

I already tried to reverse engineer the migrations file, but still not all test are passing.
Would it be possible for you to provide the migrations structure ?

cheers !

Your requirements could not be resolved to an installable set of packages.

โžœ  hrhunter.run git:(development) โœ— composer require laracraft-tech/laravel-schema-rules --dev  
./composer.json has been updated
Running composer update laracraft-tech/laravel-schema-rules
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- laravel/framework is locked to version v10.35.0 and an update of this package was not requested.
- carbonphp/carbon-doctrine-types 3.0.0 conflicts with doctrine/dbal 3.7.2.
- nesbot/carbon 2.72.0 requires carbonphp/carbon-doctrine-types * -> satisfiable by carbonphp/carbon-doctrine-types[3.0.0].
- laracraft-tech/laravel-schema-rules[v1.0.0, ..., v1.3.5] require doctrine/dbal ^3.6 -> satisfiable by doctrine/dbal[3.6.0, ..., 3.7.2].
- laravel/framework v10.35.0 requires nesbot/carbon ^2.67 -> satisfiable by nesbot/carbon[2.72.0].
- Root composer.json requires laracraft-tech/laravel-schema-rules * -> satisfiable by laracraft-tech/laravel-schema-rules[v1.0.0, ..., v1.3.5].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require laracraft-tech/laravel-schema-rules:*" to figure out if any version is installable, or "composer require laracraft-tech/laravel-schema-rules:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
โžœ  hrhunter.run git:(development) โœ— 

composer.json

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The skeleton application for the Laravel framework.",
    "keywords": ["laravel", "framework"],
    "license": "MIT",
    "require": {
        "php": "^8.1",
        "guzzlehttp/guzzle": "^7.2",
        "laravel/framework": "^10.10",
        "laravel/sanctum": "^3.3",
        "laravel/tinker": "^2.8",
        "spatie/laravel-permission": "^6.1"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/pint": "^1.0",
        "laravel/sail": "^1.18",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^7.0",
        "phpunit/phpunit": "^10.1",
        "spatie/laravel-ignition": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "allow-plugins": {
            "pestphp/pest-plugin": true,
            "php-http/discovery": true
        }
    },
    "minimum-stability": "stable",
    "prefer-stable": true
}

I just created the project. Only used "laravel new"

Tables outside the public database schema

In postgres tables outside the public schema are found but the validator does not generate.
Example:
admin.servers

 public function up(): void
    {
        Schema::create('admin.servers', function (Blueprint $table) {
            $table->id();
            $table->string('nome')->index();
            $table->string('cpf')->unique()->index();
            $table->enum('sexo', SexoEnum::values())->nullable();
            $table->enum('estado_civil', EstadoCivilEnum::values())->nullable();
            $table->date('data_nascimento')->nullable();
            $table->timestamps();
        });
    }
    
Schema-based validation rules for table "admin.servers" have been generated!
Copy & paste these to your controller validation or form request or where ever your validation takes place:
[]

Unique columns not being set

I found another issue with unique columns that are not being set as unique in the rules. For instance I have the guid column that is set as unique in the table definitions, and when generating the rules it sets as follows: 'guid' => ['required', 'string', 'min:1', 'max:191'] where it should be 'guid' => ['required', 'string', 'min:1', 'max:191', 'unique:table_name,guid']
Please note that these are constructive contributions to make the package even better.

Boolean rules always set to required

Great package, but I found that the boolean (TINYINT) is always set to 'some_field' => ['required', 'boolean'], when we know that by default, checkboxes and other boolean fields, if not checked or selected, will not be present in the request payload, therefore the creation of the rules for boolean values should, IMHO, be treated as ['sometimes', 'boolean'].

Table prefix not supported

Config

image

Without prefix

โ•ฐโ”€ php artisan schema:generate-rules zone                                                                                                                                    โ”€โ•ฏ

   Illuminate\Database\QueryException 

  SQLSTATE[42S02]: Base table or view not found: 1146 Table 'clothinggm_test.zone' doesn't exist (Connection: mysql, SQL: SHOW COLUMNS FROM zone)

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:822
    818โ–•                     $this->getName(), $query, $this->prepareBindings($bindings), $e
    819โ–•                 );
    820โ–•             }
    821โ–• 
  โžœ 822โ–•             throw new QueryException(
    823โ–•                 $this->getName(), $query, $this->prepareBindings($bindings), $e
    824โ–•             );
    825โ–•         }
    826โ–•     }

  i   A table was not found: You might have forgotten to run your database migrations. 
      https://laravel.com/docs/master/migrations#running-migrations

      +22 vendor frames 

  23  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

With prefix

โ•ฐโ”€ php artisan schema:generate-rules fz_zone                                                                                                                                 โ”€โ•ฏ

   LaracraftTech\LaravelSchemaRules\Exceptions\TableDoesNotExistException 

  Table 'fz_zone' not found!

  at vendor/laracraft-tech/laravel-schema-rules/src/Commands/GenerateRulesCommand.php:82
     78โ–•             throw new MultipleTablesSuppliedException($msg);
     79โ–•         }
     80โ–• 
     81โ–•         if (! Schema::hasTable($table)) {
  โžœ  82โ–•             throw new TableDoesNotExistException("Table '$table' not found!");
     83โ–•         }
     84โ–• 
     85โ–•         if (empty($columns)) {
     86โ–•             return;

      +13 vendor frames 

  14  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

error generating from mysql table

Thanks for writing this, going to save us all a heap of time.

php 8.1.12 Ubuntu
Laravel Framework 10.15.0
mysql 5.8 (latest up to date)

to Replicate ...
php artisan schema:generate-rules quotes

Error ...
ErrorException

Undefined array key "int(11)"

at vendor/laracraft-tech/laravel-schema-rules/src/Resolvers/SchemaRulesResolverMySql.php:93
89โ–• case $type->contains('int'):
90โ–• $columnRules[] = "integer";
91โ–• $sign = ($type->contains('unsigned')) ? 'unsigned' : 'signed' ;
92โ–• $intType = $type->before(' unsigned')->__toString();
โžœ 93โ–• $columnRules[] = "min:".self::$integerTypes[$intType][$sign][0];
94โ–• $columnRules[] = "max:".self::$integerTypes[$intType][$sign][1];
95โ–•
96โ–• break;
97โ–• case $type->contains('double') ||

  +15 vendor frames 

16 artisan:37
Illuminate\Foundation\Console\Kernel::handle()

Table Structure
Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
quotename varchar(255) YES
carrid int(11) NO 0
siteid int(11) YES 0
contactid int(11) NO -1
dateissued date NO NULL
dateeffective date NO NULL
dateexpires date NO NULL
commodity char(25) YES NULL
hcode char(30) YES NULL
priority char(25) YES NULL
lodgepoint char(20) YES NULL
orig char(3) YES NULL
remarks text YES NULL
notes text YES NULL
final char(3) YES NULL

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.