Avatar of Marco Gasi
Marco Gasi
Flag for Spain asked on

Laravel form validation error

Hi everybody.
I'm learning Laravel and I've got an issue with the Auth code. The issue is that Laravel seems to pretend that to register a new user all registration form fields be filled, even the not required ones.

This is my RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;

class RegisterController extends Controller
{
  /*
  |--------------------------------------------------------------------------
  | Register Controller
  |--------------------------------------------------------------------------
  |
  | This controller handles the registration of new users as well as their
  | validation and creation. By default this controller uses a trait to
  | provide this functionality without requiring any additional code.
  |
  */

  use RegistersUsers;

  /**
   * Where to redirect users after registration.
   *
   * @var string
   */
  protected $redirectTo = RouteServiceProvider::HOME;

  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
    $this->middleware('guest');
  }

  /**
   * Get a validator for an incoming registration request.
   *
   * @param  array  $data
   * @return \Illuminate\Contracts\Validation\Validator
   */
  protected function validator(array $data)
  {
    return Validator::make($data, [
      'name' => ['required', 'string', 'max:255'],
      'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
      'password' => ['required', 'string', 'min:8', 'confirmed'],
      'company' => ['string'],
      'website' => ['string'],
      'phone' => ['numeric'],
      'mobile' => ['numeric'],
      'type' => ['string'],
    ]);
  }

  /**
   * Create a new user instance after a valid registration.
   *
   * @param  array  $data
   * @return \App\User
   */
  protected function create(array $data)
  {
    return User::create([
      'name' => $data['name'],
      'email' => $data['email'],
      'password' => Hash::make($data['password']),
     //using data_get doesn't change anything
      'company' => data_get( $data, 'company'),
      'website' => data_get($data, 'website'),
      'phone' => data_get($data, 'phone'),
      'mobile' => data_get($data, 'mobile'),
    	'type' => data_get($data, 'type'),
      // 'company' => $data['company'],
      // 'website' => $data['website'],
      // 'phone' => $data['phone'],
      // 'mobile' => $data['mobile'],
    	// 'type' => $data['type'],
    ]);
  }

  /**
   * https://laraveldaily.com/auth-after-registration-redirect-to-previous-intended-page/
   * Handle a registration request for the application.
   *
   * @param  \Illuminate\Http\Request  $request
   * @return \Illuminate\Http\Response
   */
  public function register(Request $request)
  {
    $this->validator($request->all())->validate();

    event(new Registered($user = $this->create($request->all())));

    $this->guard()->login($user);

    return $this->registered($request, $user)
      ?: redirect()->intended($this->redirectPath());
  }

}

Open in new window


I originally followed a tutorial. Later I wanted to add some field to user table and I used this migration:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddPersonalDataToUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('company')->nullable();
            $table->string('website')->nullable();            
            $table->string('phone')->nullable();            
            $table->string('mobile')->nullable();            
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['company',  'website', 'phone', 'mobile']);
        });
    }
}

Open in new window


I thought that leaving added columns empty whould have worked fine but I've got validation errors like "The website must be a string", so I googled a bit and I have created a new migration:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddDefaultNullToSomeColumn extends Migration
{
	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::table('users', function (Blueprint $table) {
			$table->string('company')->nullable()->default(null)->change();
			$table->string('website')->nullable()->default(null)->change();
			$table->string('phone')->nullable()->default(null)->change();
			$table->string('mobile')->nullable()->default(null)->change();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::table('users', function (Blueprint $table) {
			$table->string('company')->nullable()->change();
			$table->string('website')->nullable()->change();
			$table->string('phone')->nullable()->change();
			$table->string('mobile')->nullable()->change();
		});
	}
}

Open in new window


and finally, here there is my registration form
@extends('master')
@section('title', __('auth.registerTitle') )

@section('content')
<div class="hero-wrap hero-wrap-2" style="background-image: url('/images/bg_2b.jpg');" data-stellar-background-ratio="0.5">
  <div class="overlay"></div>
  <div class="container">
    <div class="row no-gutters slider-text align-items-center justify-content-center">
      <div class="col-md-8 ftco-animate text-center text-center mt-5">
        <p class="breadcrumbs mb-0"><span class="mr-3"><a href="/">{{ __('menu.home') }} <i class="ion-ios-arrow-forward"></i></a></span> <span>{{ __('auth.menu-register') }}</span></p>
        <h1 class="mb-3 bread">{{ __('auth.menu-register') }}</h1>
      </div>
    </div>
  </div>
</div>

<section class="ftco-section ftco-partner">
  <div class="container">
    <div class="row block-9 justify-content-center mb-5">
      <div class="col-md-10 mb-md-5">

        <h2 class="float-left">{{ __('auth.registerTitle') }}</h2>
        <form method="post">
          @foreach ($errors->all() as $error)
            <p class="alert alert-danger">{{ $error }}</p>
          @endforeach

          {{ csrf_field() }}
          <div class="form-group">
          <label for="name" class="col-lg-12 control-label">{{ __('auth.name') }}</label>
            <div class="col-lg-12">
              <input type="text" class="form-control" id="name" placeholder="{{ __('auth.name') }}" name="name" value="{{ old('name') }}">
            </div>
          </div>

          <div class="form-group">
            <label for="email" class="col-lg-12 control-label">{{ __('auth.email') }}</label>
            <div class="col-lg-12">
              <input type="email" class="form-control" id="email" placeholder="{{ __('auth.email') }}" name="email" value="{{ old('email') }}">
            </div>
          </div>

          <div class="form-group">
            <label for="password" class="col-lg-12 control-label">{{ __('auth.pwd') }}</label>
            <div class="col-lg-12">
              <input type="password" class="form-control"  name="password">
            </div>
          </div>

          <div class="form-group">
            <label for="password" class="col-lg-12 control-label">{{ __('auth.pwdrepeat') }}</label>
            <div class="col-lg-12">
              <input type="password" class="form-control"  name="password_confirmation">
            </div>
          </div>

          <div class="form-group">
            <label for="company" class="col-lg-12 control-label">{{ __('auth.company') }}</label>
            <div class="col-lg-12">
              <input type="text" class="form-control" id="company" placeholder="{{ __('auth.company') }}" name="company" value="{{ old('company') }}">
            </div>
          </div>

          <div class="form-group">
            <label for="website" class="col-lg-12 control-label">{{ __('auth.website') }}</label>
            <div class="col-lg-12">
              <input type="text" class="form-control" id="website" placeholder="{{ __('auth.website') }}" name="website" value="{{ old('website') }}">
            </div>
          </div>

          <div class="form-group">
            <label for="phone" class="col-lg-12 control-label">{{ __('auth.phone') }}</label>
            <div class="col-lg-12">
              <input type="text" class="form-control" id="website" placeholder="{{ __('auth.phone') }}" name="phone" value="{{ old('phone') }}">
            </div>
          </div>

          <div class="form-group">
            <label for="mobile" class="col-lg-12 control-label">{{ __('auth.mobile') }}</label>
            <div class="col-lg-12">
              <input type="text" class="form-control" id="mobile" placeholder="{{ __('auth.mobile') }}" name="mobile" value="{{ old('mobile') }}">
            </div>
          </div>

          {{-- <div class="form-group">
            <label for="type" class="col-lg-12 control-label">{{ __('auth.type') }}</label>
            <div class="col-lg-12">
                <select class="form-control" name="type" id="type">
                    <option value="admin">Admin</option>
                    <option value="super_admin">Super Admin</option>
                    <option value="member">Member</option></select>
            </div>
          </div> --}}

          <div class="form-group">
            <div class="col-lg-10 col-lg-offset-2">
							<input type="hidden" name="type" id="type" value="member" />
              <button type="reset" class="btn btn-default">{{ __('auth.cancel') }}</button>
              <button type="submit" class="btn btn-primary">{{ __('auth.submit') }}</button>
            </div>
          </div>
        </form>
      </div>
    </div>
  </div>
</section>
@endsection

Open in new window

Actually, the db table allows those fields to be NULL and their default value is NULL but I still get those errors and to successfully register a new user I must fill all fields in the form.
What I am missing here?
LaravelPHP

Avatar of undefined
Last Comment
Marco Gasi

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
Chris Stanyon

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Marco Gasi

ASKER
Hi Chris, thank you for your answer.
I'm using Laravel 6.0.
I thought that just declaring fields as nullable in the migration were enough :)
Going to try your suggestion.
Marco Gasi

ASKER
Thank you, Chris, it works like a charm.
Chris Stanyon

No worries Marco,

Glad I could help.

FYI -  the Validations in your controller, aren't directly related to the tables (although it will help to prevent invalid data being saved to your DB)
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Marco Gasi

ASKER
the Validations in your controller, aren't directly related to the tables (although it will help to prevent invalid data being saved to your DB)
I'm not sure to understand what you mean.... Actually, no, I'm absolutely sure I don't :)
Chris Stanyon

Hey Marco,

In your comments you said that the DB columns allow null but you still get the error.

My point was that you're dealing with 2 separate issues here - when you post a form to a controller, you validate the data against a set of rules. Your data either passes or fails the validation. This has nothing to do with your Database, the Tables or the Columns - you're simply validating the data a user has submitted.

After the data has been validated, you then store that data into the database - as a separate process.

That's why I said that the Validations aren't related to your Tables.
Marco Gasi

ASKER
Okay, thank you so much for the additional input, very clear. Ciao.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.