We help IT Professionals succeed at work.

How to insert a record into Laravel's User table...?

Bruce Gust
Bruce Gust asked
on
I want to be able to insert a user into the user table Laravel creates by default as a result of "php artisan auth." Basically, I'm adding a column to that table that gives my user administrative privileges.

I've got it done, for the most part, but there's one thing that keeps alluding me: I want to be able to create a "request" file where I can document some validation rules. When I do that, I get some errors and I'll elaborate on that in just a minute.

The one thing I've found recently is that when you look at the User model, you see this:

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

Open in new window


From what I gather, "authenticatable" is going to invoke some validation rules by default. On top of that, when you look at the Controller that is made by the "auth" command, you see this:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

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 = '/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'],
        ]);
    }

    /**
     * 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']),
        ]);
    }
}

Open in new window


In other words, it seems like there's some validation built into this table by default and any attempt on my part to create a Request is going to step on some toes and probably generate some errors.

At least that's what I'm thinking.

When I run this code:

   public function store([b]CreateUserRequest[/b] $request)
    {
		$user = new User;
		if($request->input('admin_yes')=="Y") {
			$user->admin=1;
		}
		else {
			$user->admin=0;
		}
		$user->user_id = $request->input('user_id');
		$user->name=$request->input('name');
		$user->email=$request->input('email');
		$user->password = Hash::make($request->input('password'));
		$success='User was successfully created!';
		
		if($user->save()) {
			return View::make('/admin/displayUser')
			->with('user', $user)
			->with('newUser', 'Here\'s the user you just entered!')
			->with('adminPermissions', 'yes');
		}
    }

Open in new window


I get this error:

Method Illuminate\Validation\Validator::validateu{wud does not exist.

No idea where that's coming from or what it means.

But when I change the above code from this:

 public function store(CreateUserRequest $request)

to this:

 public function store(Request $request)

...no problem.

Granted, I may just go with the RegisterController.php page and stop trying to reinvent the wheel, but I want to understand what's going on under the hood.

Any ideas?
Comment
Watch Question

Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Bruce,

By using Authenticatable, you're not adding any Validation rules - you're just adding some additional methods, so that's not causing any additional Validation.

In your RegisterController, you are using the RegisterUsers trait. Behind the scenes, this adds a register() method, which in turn calls your validator() method and if that passes it then calls your create() method. If you set up a POST route to this register() method, then that's how you usually regsiter Users on your site.

Your store() method is independent of all of that. Registering a User is not the same as creating a User and the two aren't tied together.

In your store method, you are using a CreateUserRequest instead of the standard Request, so I'm assuming you've ran php artisan make:request CreateUserRequest. This extends the FormRequest class and that will automatically fire validation based on the rules you've set in there. It sounds like the problem is with your CreateUserRequest class, so have a look in there.

Also, the error you've posted looks off - I'm guessing it's a typo, but it does look odd.

Method Illuminate\Validation\Validator::validateu{wud does not exist

Maybe repost the exact error.
Bruce GustPHP Developer

Author

Commented:
No, that's the error and that's part of what makes this whole thing so exasperating.

And yes, I did run php artisan make:request CreateUserRequest.

What do you think?
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hmm. Maybe you have some kind of corruption going on because this doesn't make any sense:

:validateu{wud

Post up your code for the CreateUserRequest, as I think that's the source of your problem (or it's related to that file). Also, double check your View that contains your Form to make sure you've don't have something odd going on in there. Those strange characters that you're getting indicate a bigger problem somewhere
Bruce GustPHP Developer

Author

Commented:
Here you go:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateUserRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
           'name' => 'required' | 'string' | 'max:255',
            'email' => 'required' | 'string' | 'email' | 'max:255' | 'unique:users',
            'password' => 'required' | 'string' | 'min:8' | 'confirmed'
        ];
    }
	
	public function messages()
    {
        return [
            'name is.required' => 'name is required!',
            'email is.required' => 'email is required!',
			'password is.confirmed' => 'make sure both your "password" and your "confirm password" fields match!'
        ];
    }
}

Open in new window

Most Valuable Expert 2018
Distinguished Expert 2019
Commented:
Right.

Couple of issues. First off, your rules are wrong. You should be returning an array where the key is the field and the value is a pipe delimited string of validation rule. You have this:

return [
    'name' => 'required' | 'string' | 'max:255',
    ...

What you should have is this:

return [
    'name' => 'required|string|max:255',
    ...

Secondly, your validation errors look a little off. You should dot delimit the property and the rule:

return [
    'name.required' => 'name is required!',
    'email.required' => 'email is required!',
    'password.confirmed' => 'make sure both your "password" and your "confirm password" fields match!'
];
Bruce GustPHP Developer

Author

Commented:
BAM!

Thank you!

I'm taking notes on this stuff too, Chris! That was one weird error, but you nailed it.

Thanks!
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:

No worries Bruce