Stop using laravelcollective/html instead of write your forms with classic html tags.
Problem with user store and update
Hello,
I have created a UserController to CRUD users. But I have a problem (only with the user controller, not with other controllers).
When I click on save or update, instead of routing with post or put method, it is routing with get method. What's strange is that I have exactly the same code as in the other contollers.
Here is my blade code for updating a user.
```{{ Form::model($user, ['route' => ['users.update', $user]]) }}
{{ csrf_field() }}
{{ method_field('PUT') }}
{{ some fields here }}
@include('users._form', ['submitButtonText' => 'Modifier l\'utilisateur'])
{!! Form::close() !!}```
Do you have any idea of the problem ?
Thanks for your help.
Vincent
Ok ... but do you have any idea of the problem ? why is there a problem with the users and not with my categories or courses ?
Would the problem be Collective ? When I have a look at the HTML code, it looks good.
@michaloravec I have tried with a classic html tags form, and the problem is the same. No solution yet ...
@vincent15000 Show your other code.
Maybe you can check in your routes file to see if you have a typo in the routes names
@thibaultvanc that's already done ... the routes are ok
@michaloravec here is my other code
please I have forgotten how to have a pretty code on a black background ... my three ``` are visible ... perhaps something other ?
In the controller
```/**
* Show the form for editing the specified resource.
*
* @param \App\course $course
* @return \Illuminate\Http\Response
*/
public function edit(User $user)
{
return view('users.edit', compact('user'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\course $course
* @return \Illuminate\Http\Response
*/
public function update(UserFormRequest $request, User $user)
{
$user->fill($request->all());
$user->update();
return redirect()->route('users.show', compact('user'));
}```
In the model form request
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'username' => [
'required',
'string',
'max:255',
Rule::unique('users')->ignore(Auth::user()->id)],
'firstname' => ['string', 'max:255', 'nullable'],
'lastname' => ['string', 'max:255', 'nullable'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore(Auth::user()->id)],
'password' => ['required', 'string', 'min:8', 'confirmed']
];
}```
maybe you can share your route file ?
And the method declared is PUT :
{{ method_field('PUT') }}
But when I look at the log, the method is GET.
@thibaultvanc here are my routes
Route::get('/', 'HomeController@index')->name('home');
Auth::routes();
Route::namespace('Admin')->group(function () {
Route::middleware(['auth'])->group(function()
{
Route::get('dashboard', 'DashboardController@index')->name('dashboard');
Route::resource('users', 'UserController');
Route::resource('categories', 'CategoryController')->except(['show']);
Route::resource('courses', 'CourseController')->except(['show']);
});
Route::resource('categories', 'CategoryController')->only(['show']);
Route::resource('courses', 'CourseController')->only(['show']);
});
maybe php artisan route:list can help you
@vincent15000 Show your current view.
Also change
$user->fill($request->all());
$user->update();
to this
$user->update($request->all());
Result will be same.
@thibaultvanc I have done it ... php artisan route:list all seems to be good ... but it doesn't work ... grrrrr
| | GET|HEAD | users | users.index | App\Http\Controllers\Admin\UserController@index | web |
| | | | | | auth |
| | POST | users | users.store | App\Http\Controllers\Admin\UserController@store | web |
| | | | | | auth |
| | GET|HEAD | users/create | users.create | App\Http\Controllers\Admin\UserController@create | web |
| | | | | | auth |
| | DELETE | users/{user} | users.destroy | App\Http\Controllers\Admin\UserController@destroy | web |
| | | | | | auth |
| | PUT|PATCH | users/{user} | users.update | App\Http\Controllers\Admin\UserController@update | web |
| | | | | | auth |
| | GET|HEAD | users/{user} | users.show | App\Http\Controllers\Admin\UserController@show | web |
| | | | | | auth |
| | GET|HEAD | users/{user}/edit | users.edit | App\Http\Controllers\Admin\UserController@edit | web |
| | | | | | auth |
The content of the update method is not executed. So the problem is before the update method. When there are some input errors, the errors are written ... but when there are no errors, the click on the update button does only one thing : reload the page.
Could it be a problem with the password field which is not in the edit view ?
No, how I said post your current view file.
@extends('layouts.app')
@section('content')
<div class="container">
<div class="card">
<div class="card-header d-flex">
<div class="mr-auto align-self-center"><h5>Modifier l'utilisateur</h5></div>
<div><a class="btn btn-primary" href="{{ route('users.show', $user) }}" role="button">Annuler</a></div>
</div>
<div class="card-body">
{{ Form::model($user, ['route' => ['users.update', $user]]) }}
{{ csrf_field() }}
{{ method_field('PUT') }}
@include('users._form', ['submitButtonText' => 'Modifier l\'utilisateur'])
{!! Form::close() !!}
</div>
</div>
</div>
@endsection
Inside the _form.blade.php file, there are only fields.
<div class="form-group">
{{ Form::label('username', 'Nom d\'utilisateur', ['class' => 'control-label']) }}
{{ Form::text('username', null, ['class' => $errors->has("username") ? "form-control is-invalid" : "form-control", 'placeholder' => 'Nom d\'utilisateur']) }}
{!! $errors->first('username', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group">
{{ Form::label('lastname', 'Nom', ['class' => 'control-label']) }}
{{ Form::text('lastname', null, ['class' => $errors->has("lastname") ? "form-control is-invalid" : "form-control", 'placeholder' => 'Nom']) }}
{!! $errors->first('lastname', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group">
{{ Form::label('firstname', 'Prénom', ['class' => 'control-label']) }}
{{ Form::text('firstname', null, ['class' => $errors->has("firstname") ? "form-control is-invalid" : "form-control", 'placeholder' => 'Prénom']) }}
{!! $errors->first('firstname', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group">
{{ Form::label('email', 'Adresse mail', ['class' => 'control-label']) }}
{{ Form::text('email', null, ['class' => $errors->has("email") ? "form-control is-invalid" : "form-control", 'placeholder' => 'Adresse mail']) }}
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group">
{{ Form::submit($submitButtonText, ['class' => 'btn btn-success btn-block']) }}
</div>
This is pure html? Wihout laravelcollective/html?
Problem will be propably with this 'Nom d\'utilisateur'
Change it to "Nom d'utilisateur" and don't use laravelcollective/html!
How do you know that it generate a GET ? maybe you are just redirected by the validator ?
try to add
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@michaloravec not pure html ... but I said that there is exactly the same problem with pure html @thibaultvanc yes it could be ... oh I will try without the validator and I tell you something
Then show me your pure html...
@thibaultvanc well ... the problem comes from the validator
what's wrong with this ?
'username' => [
'required',
'string',
'max:255',
Rule::unique('users')->ignore(Auth::user()->id)],
'firstname' => ['string', 'max:255', 'nullable'],
'lastname' => ['string', 'max:255', 'nullable'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore(Auth::user()->id)],
'password' => ['required', 'string', 'min:8', 'confirmed']
Add this to your view and you will see it where is the problem.
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
try to add this in your blade
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
to see wich field does not pass the validation. If the validation does not pass, Laravel return to the previous page, so you feel like making a GET If your blade does not show the errors
@michaloravec ok thanks ... the problem is that the password field is required ...
I thought I could update without the password, even if it is required ... I thought that required was only for the available fields in the view ... and I have no password field in that view
so I have to exclude the password from the update fields
what I want to do in the possibility to update a user without updating his password ... how can I do that ? the password field is required, but only required when you have to connect
replace required by nullable in
'password' => ['required', 'string', 'min:8', 'confirmed']
Remove this line from validation rules
'password' => ['required', 'string', 'min:8', 'confirmed']
@thibaultvanc @michaloravec I have already thought about this solution, but doing so could be dangerous, couldn't it ? This means that a visitor who wants to register could register without any password.
Is it possible to set up a rule only for some methods in the controller or for some routes and not for others ?
This is resource for users in the Administration where only admin can manage user.
For registration you have there https://laravel.com/docs/7.x/authentication
And you use it with Auth::routes();
So it's different things.
How I said just remove this line from your validation rules
'password' => ['required', 'string', 'min:8', 'confirmed']
And mark this thread as solved. Thanks.
Ok thanks for your help.
Please or to participate in this conversation.