Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rpd's avatar
Level 3

SQL Error: Column not found

I'm using Laravel 8 with Fortify installed. Currently I'm working on functionality for the user to edit their profile or their account settings, which I've split into two different routes and therefore two different methods inside UpdateUserProfileInformation.php.

When I submit the 'edit profile' form, everything works perfectly, but with the 'account settings' form I get this error

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause'

I am using a custom primary key for this table, which I have updated in the User class using

protected $primaryKey = 'user_id';  

I'm not sure why it is still searching for id rather than user_id and why this issue only exists in the updateSettings method and not updateProfile.

I could just combine everything into one form and fix the issue but I'd like to learn where this issue is stemming from or what I have done wrong.

Here's my code:

Inside the routes file:

if (Features::enabled(Features::updateProfileInformation())) {

      Route::get('/users/{user:username}/edit-profile', [UserProfileController::class, 'edit'])->middleware(['verified'])->name('edit-profile');

      Route::put('/users/{user:username}/edit-profile', [UserProfileController::class, 'update'])->middleware(['auth']);

      Route::get('/users/{user:username}/settings', [UserSettingsController::class, 'edit'])->middleware(['verified'])->name('account-settings');

      Route::put('/users/{user:username}/settings', [UserProfileController::class, 'update'])->middleware(['auth']);
}

UserProfileController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
use App\Models\User;
use App\Traits\Countries as Countries;

class UserProfileController extends Controller
{

    use Countries;

    /**
    * Update the user's profile information.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Laravel\Fortify\Contracts\UpdatesUserProfileInformation  $updater
    * @return \Illuminate\Http\Response
    */
    public function update(Request $request, UpdatesUserProfileInformation $updater){

       $updater->update($request->user(), $request->all());

       return $request->wantsJson()
             ? new JsonResponse('', 200)
             : redirect(auth()->user()->path())->with('status', 'profile-information-updated');
    }

UpdateUserProfileInformation.php:

<?php

namespace App\Actions\Fortify;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;

class UpdateUserProfileInformation implements UpdatesUserProfileInformation
{
    /**
     * Validate and update the given user's profile information.
     *
     * @param  mixed  $user
     * @param  array  $input
     * @return void
     */
    public function update($user, array $input, $onboarding = false)
    {

        if (strpos(url()->current(), 'edit-profile')) {
            $this->updateProfile($user, $input, $onboarding);
        }else{
            $this->updateSettings($user, $input);
        }

    }

    /**
     * Validate and update the given user's profile information.
     *
     */
    public function updateProfile($user, array $input, $onboarding)
    {
        // dd($input);

        Validator::make($input, [
            'name' => ['string', 'max:255', 'nullable'],
            'country' => ['exists:country,country_id', 'nullable'],
            'bio' => ['string', 'max:255', 'nullable'],
            'profile_pic_path' => ['file', 'nullable'],
            'website' => ['url', 'max:255', 'nullable'],
            '_500px' => ['string', 'max:255', 'nullable'],
            'twitter' => ['string', 'max:255', 'nullable'],
            'instagram' => ['string', 'max:255', 'nullable'],
            'flickr' => ['string', 'max:255', 'nullable'],
            'vsco' => ['string', 'max:255', 'nullable'],
        ])->validate();

        $user->forceFill([
            'display_name' => $input['name'],
            'country_id' => $input['country'],
            'bio' => $input['bio'],
            'website' => $input['website'],
            '_500px_username' => $input['_500px'],
            'twitter_username' => $input['twitter'],
            'instagram_username' => $input['instagram'],
            'flickr_username' => $input['flickr'],
            'vsco_username' => $input['vsco'],
            'completed_onboarding' => $onboarding,
         ])->save();
    }


   /**
    * Update user settings on db
    */

    public function updateSettings($user, array $input)
    {


      Validator::make($input, [
          'email' => [
               'required',
               'string',
               'email',
               'max:255',
               Rule::unique('users')->ignore($user->email),
          ],
          'username' => [
               'required',
               'string',
               'min:3',
               'max:255',
               'regex:/^[a-z0-9_.]+$/',
               Rule::unique('users')->ignore($user->username),
          ],

      ])->validate();


      if ($input['email'] !== $user->email && $user instanceof MustVerifyEmail) {
          $this->updateVerifiedUser($user, $input);
      } else {
          $user->forceFill([
             'username' => $input['username'],
             'subscribed_newsletter' => $input['sub_newsletter'],
             'subscribed_email_notifications' => $input['sub_email_notifications'],
          ])->save();
      }

    }

   /**
    * Update the given verified user's profile information.
    *
    * @param  mixed  $user
    * @param  array  $input
    * @return void
    */
   protected function updateVerifiedUser($user, array $input)
   {
       $user->forceFill([
           'username' => $input['username'],
           'email' => $input['email'],
           'email_verified_at' => null,
           'subscribed_newsletter' => $input['sub_newsletter'],
           'subscribed_email_notifications' => $input['sub_email_notifications'],
       ])->save();

       $user->sendEmailVerificationNotification();
   }

   /**
    * Update the given user's profile picture.
    *
    * @param  mixed  $user
    * @return void
    */
   public function updateProfilePicture($user){

     $profilePic = request('profile_picture')->store('profile-pics');

     $user->forceFill([
       'profile_pic_path' => $profilePic,
     ])->save();

  }

}

Problem seems to happen when the validator checks the email/username uniqueness.

Thanks

0 likes
7 replies
jlrdw's avatar

You shouldn't need an id, use Auth::id for the query.

Click My Participation here in forum, no id used, it is Auth::id().

Snapey's avatar

from the docs (correct paragraph this time)

If your table uses a primary key column name other than id, you may specify the name of the column when calling the ignore method:

Rule::unique('users')->ignore($user->id, 'user_id')
1 like
rpd's avatar
Level 3

Hmm, now I'm getting validation errors:

"That username has already been taken." and "That email address has already been taken."

Snapey's avatar

and is also incorrect. It should be excluding rows that belong to the current user. You should ignore the user not the field you are validating.

eg

Rule::unique('users')->ignore($user->user_id, 'user_id')

i'm confused though... you are validating email but not saving it to the user's account

rpd's avatar
Level 3

Ahhh,

you may also pass the entire model instance. Laravel will automatically extract the key from the model:

Rule::unique('users')->ignore($user)

This works! Thanks for your help - I should read the docs more! :P

Snapey's avatar

passing the entire user model as in

Rule::unique('users')->ignore($user)
1 like
rpd's avatar
Level 3

Ah whoops, sorry typo! Yep, have corrected above.

Please or to participate in this conversation.