I am trying to make a profile settings page where people can chane name email and password and only the password gets updated but all the rest remain the same. I cant understand why below i have the code Note i use breeze
settings.blade.php
<x-app-layout>
<x-slot name="header">
<h2 >
{{ __('Settings') }}
</h2>
</x-slot>
<div >
<div >
<div >
<div >
<!-- Personal Details heading -->
<div >
<h2 >
{{ __('Personal Details') }}
</h2>
</div>
<!-- Show id with prefix-->
<div >
<x-label for="id" :value="__('ID')" />
<x-input id="id" type="text" name="id" :value="Auth::user()->id 243254" disabled />
</div>
<form method="POST" action="{{ route('settings.update')}}">
@method('PUT')
@csrf
<div >
<div >
<div>
<x-label for="name" :value="__('Name')" />
<x-input id="name" type="text" name="name" value="{{ auth()->user()->name }}" autofocus />
</div>
<br />
<div>
<x-label for="email" :value="__('Email')" />
<x-input id="email" type="email" name="email" value="{{ auth()->user()->email }}" autofocus />
</div>
</div>
<br />
<div >
<div>
<x-label for="new_password" :value="__('New password')" />
<x-input id="new_password"
type="password"
name="password"
autocomplete="new-password" />
</div>
<br />
<div>
<x-label for="confirm_password" :value="__('Confirm password')" />
<x-input id="confirm_password"
type="password"
name="password_confirmation"
autocomplete="confirm-password" />
</div>
</div>
</div>
<div >
<x-button >
{{ __('Update') }}
</x-button>
</div>
</form>
<!-- Address History heading -->
<div >
<h2 >
{{ __('Address History') }}
</h2>
</div>
<br />
<form method="POST" action="#">
@csrf
<!-- Previous Addresses History Table using tr -->
<table>
<tr>
<th>Address</th>
<th>Postcode</th>
<th>City</th>
<th>Country</th>
<th>From</th>
<th>To</th>
</tr>
</table>
<br />
<!--Add heading to add new address-->
<h3 >
{{ __('Add new address') }}
</h3>
<br />
<!-- New Address form-->
<div >
<div >
<div>
<x-label for="address" :value="__('Address')" />
<x-input id="address" type="text" name="address" value="{{ auth()->user()->address }}" autofocus />
</div>
<br />
<div>
<x-label for="city" :value="__('City')" />
<x-input id="city" type="text" name="city" value="{{ auth()->user()->city }}" autofocus />
</div>
</div>
<br />
<div >
<div>
<x-label for="state" :value="__('State')" />
<x-input id="state" type="text" name="state" value="{{ auth()->user()->state }}" autofocus />
</div>
<br />
<div>
<x-label for="zip" :value="__('Zip')" />
<x-input id="zip" type="text" name="zip" value="{{ auth()->user()->zip }}" autofocus />
</div>
</div><br />
<!-- add from to which day living in this address-->
<div >
<div>
<x-label for="from" :value="__('From')" />
<x-input id="from" type="date" name="from" value="{{ auth()->user()->from }}" autofocus />
</div>
<br />
<div>
<x-label for="to" :value="__('To')" />
<x-input id="to" type="date" name="to" value="{{ auth()->user()->to }}" autofocus />
</div>
</div>
<div >
<x-button >
{{ __('Add Address') }}
</x-button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
SettingsController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UpdateSettingsRequest;
use Illuminate\Http\Request;
class SettingsController extends Controller
{
public function update(UpdateSettingsRequest $request){
auth()->user()->update($request->only('name', 'email'));
if ($request->input('password')){
auth()->user()->update([
'password' => bcrypt($request->input('password'))
]);
}
return redirect()->route('settings')->with('message', 'Settings updated');
}
}
web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::group(['middleware' => 'auth'], function(){
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
Route::view('settings', 'settings')->name('settings');
Route::view('creditcards', 'creditcards')->name('creditcards');
Route::view('loans', 'loans')->name('loans');
Route::put('settings', [\App\Http\Controllers\SettingsController::class, 'update'])
->name('settings.update');
});
require __DIR__.'/auth.php';
anyone knows why?
I tried to do ifs, to take out the values on the form and still
CodePudding user response:
When you use update()
the instance of the user is not altered, it runs the query directly to database.
The data are updated (reload the page and you will see the changes) but the instance in auth()->user()
is not.
I suggest you change your code to this
public function update(UpdateSettingsRequest $request){
auth()->user()->name = $request->input('name');
auth()->user()->email = $request->input('email');
if ($request->input('password')){
auth()->user()->password = bcrypt($request->input('password'));
}
auth()->user()->save();
return redirect()->route('settings')->with('message', 'Settings updated');
}
CodePudding user response:
Just get a User model instance first, then update it
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UpdateSettingsRequest;
use Illuminate\Http\Request;
class SettingsController extends Controller
{
public function update(UpdateSettingsRequest $request){
$user = User::findOrFail(auth()->user()->id);
$user->update($request->only('name', 'email'));
if ($request->input('password')){
$user->update([
'password' => bcrypt($request->input('password'))
]);
}
return redirect()->route('settings')->with('message', 'Settings updated');
}
}
BTW, your code is not pretty effective. Your are hitting the database twice because updates.
Instead of that, you should handle the password encrypt by using a mutator https://laravel.com/docs/9.x/eloquent-mutators#defining-a-mutator and Mass Assignment https://laravel.com/docs/9.x/eloquent#mass-assignment-json-columns
Said that, your model could have something like:
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* Interact with the user's password.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function password(): Attribute
{
return Attribute::make(
get: fn ($value) => $value,
set: fn ($value) => bcrypt($value),
);
}
Then in your controller just few lines:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UpdateSettingsRequest;
use Illuminate\Http\Request;
class SettingsController extends Controller
{
public function update(UpdateSettingsRequest $request){
$user = User::findOrFail(auth()->user()->id);
$user->update($request->all());
return redirect()->route('settings')->with('message', 'Settings updated');
}
}