Reputation: 33
My form submit but it isn't storing in the table. If I make dd() on Requests, the data is in, but when I do the save() dont work as expected. I want to add Users on a backoffice form just with Name, Email, Type of user and password.
Edit: I changed the question images to code to be more easier to you, sorry about the first attempt. Edit 2: Now appeared more 2 things, the validate on password_confirmation gives always false, and if I skip the validation gives me this error:
BadMethodCallException Call to undefined method App\User::forget()
Funtion store on Controller:
public function store(Request $request)
{
$dados = $request->validate(
[
'name' =>'required|min:2|max:20',
'email' =>'required|email|unique:App\User,email',
'password' =>'required|min:8',
'password_confirmation' =>'confirmed'
],
[
'required' =>'Os campos têm de ser todos preenchidos!',
'email' =>'O email tem de ser válido!',
'unique'=>'O email inserido já está registado!',
'min.name' =>'O nome tem de ter pelo menos 2 caracteres!',
'min.password' =>'A password tem de ter no minimo 8 caracteres!',
'confirmed' =>'As passwords deverão coincidir!'
]
);
$user = new User;
$user->forget('password_confirmation');
$user->fill($request->all());
$user->save();
return redirect()->route('utilizadores.index')->with('Success','Utilizador registado com sucesso!');
}
Route:
Route::resource('/admin/utilizadores', 'UserController');
Model:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $guarded = [
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token','password_confirmation'
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Form:
<div class="modal-body">
<form action="{{route('utilizadores.store')}}" method="POST" id="adicionarid">
@csrf
<input type="email" name="email" class="inputtext data" placeholder="Email">
<div class="customselect data top1">
<select name="tipo">
<option value="revisor" selected disabled>Revisor</option>
<option value="editor">Editor</option>
<option value="revisor">Revisor</option>
</select>
</div>
<input type="text" name="name" class="inputtext" placeholder="Nome">
<input type="password" name="password" class="inputtext" placeholder="Palavra-passe">
<input type="password" name="password_confirmation" class="inputtext" placeholder="Confirmar palavra-passe">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>
<button type="submit" class="btn btn-success" form="adicionarid">Guardar</button>
</div>
Upvotes: 0
Views: 525
Reputation: 7026
There are a bunch of issues I see in your code. Let's first list them out so you know what you did wrong
'password_confirmation' =>'confirmed'
I'm pretty certain this does not do what you expect it to do. the confirmed
validation rule must be used on password
, laravel will then automatically check if there is a field called password_confirmation
(field_name_confirmation
) and check if it is equal to the password
field. So your validation rules can be
'password' =>'required|min:8|confirmed',
And no need for a rule on password_confirmation
Next is
$user->forget('password_confirmation');
There's no forget
method in eloquent or laravel's query Builder, hence why you get
BadMethodCallException Call to undefined method App\User::forget()
There is forget
method on Collections
and the Arr::forget()
but that's not what you want here. But since you already have $dados
, it will be an array containing only the input fields for which you have defined rules in your validator, hence you can use $dados
when creating the user (will show how later in the answer)
Next is
$user->fill($request->all());
Never ever do this, because malicious users could add extra fields in the form, such as an id
, hence allowing them to modify existing users.
Instead you can do
$user->fill($dados);
Since $dados
only contains the fields returned by the validator, it is safer to use.
Another issue I noticed is that you have a field named tipo
in the form, but it's not present in the validator, hence you need to add it in the validator.
$dados = $request->validate(
[
'name' =>'required|min:2|max:20',
'email' =>'required|email|unique:App\User,email',
'password' =>'required|min:8|confirmed',
'tipo' =>'required' // Add whatever other validations you need
],
[
'required' =>'Os campos têm de ser todos preenchidos!',
'email' =>'O email tem de ser válido!',
'unique'=>'O email inserido já está registado!',
'min.name' =>'O nome tem de ter pelo menos 2 caracteres!',
'min.password' =>'A password tem de ter no minimo 8 caracteres!',
'confirmed' =>'As passwords deverão coincidir!'
]
);
Then you can just do
$user = new User;
$user->fill($dados);
$user->save();
Next issue is that you're not hashing passwords. Unless you want to directly save the users password in the database, you should hash password; Laravel makes hashing simple by providing a Hash
class you can use.
$dados['password'] = Hash::make($request->password);
be sure to add the use Illuminate\Support\Facades\Hash;
at the top of your file
So overall, with some tweaking your controller should be
public function store(Request $request)
{
$dados = $request->validate(
[
'name' =>'required|min:2|max:20',
'email' =>'required|email|unique:App\User,email',
'password' =>'required|min:8|confirmed',
'tipo' =>'required' // Add whatever other validations you need
],
[
'required' =>'Os campos têm de ser todos preenchidos!',
'email' =>'O email tem de ser válido!',
'unique'=>'O email inserido já está registado!',
'name.min' =>'O nome tem de ter pelo menos 2 caracteres!',
'password.min' =>'A password tem de ter no minimo 8 caracteres!',
]
);
$dados['password'] = Hash::make($request->password);
$user = new User;
$user->fill($dados);
$user->save();
return redirect()->route('utilizadores.index')->with('Success','Utilizador registado com sucesso!');
}
And it should do what you were hoping to achieve
Now, lets give you some additional tips.
Always avoid using an empty $guarded
protected $guarded = [
];
It could leave security vulnerabilities (even if you don't expose any such vulnerability, someone else who is careless might, so always try to use $fillable
instead, better safe than sorry)
protected $fillable = [
'name', 'email', 'password', 'tipo'
];
Then in your controller, you can safely use
$user = User::create($dados);
This is a more widely used method than fill()
. The $fillable
array also ensures that when using the create()
, only the attributes inside the $fillable
array get saved in the Database
Upvotes: 1