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

afoysal's avatar

User create and update using updateOrCreate()

I am creating and updating user using below code.

    public function store(Request $request)
    {
        if ($request->ajax()) {
            $request->validate([
                'name'      => 'required',
                'email'     => 'required|email|unique:users,email,' .$request->user_id,
                'password'  => 'required',
                'role'      => 'required',
            ]);

            $user = User::updateOrCreate(['id' => $request->user_id],
            [
                'name'      => $request->name,
                'email'     => $request->email,
                'role'      => $request->role,
                'password'  => Hash::make($request->password)
            ]);
        }
    }

When I am updating record Password is updating also. How can I solve the issue ?

How validation is working here 'email' => 'required|email|unique:users,email,' .$request->user_id, when I am creating a record ? Because when I am creating a record at that time $request->user_id is not available.

0 likes
8 replies
automica's avatar

@afoysal

Following C(reate), R(ead), U(pdate), D(elete) methods, your Create and Update should be distinct.

So best to separate your routes into 2, so that you have create (store) with a POST method and update with PATCH method.

if you know the user_id then you know you should be updating

Password should be optional if you are updating as a user may not want to update.

public function store(Request $request)
{
    $request->validate([
        'name' => 'required',
        'email' => 'required|email|unique:users,email,' . $request->user_id,
        'password' => 'required',
        'role' => 'required',
    ]);

    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'role' => $request->role,
        'password' => Hash::make($request->password)
    ]);
}

public function update(Request $request, User $user)
{
    $validated = $request->validate([
        'name' => 'required',
        'email' => 'required|email|unique:users,email,' . $request->user_id,
        'password' => 'optional',
        'role' => 'required',
    ]);

    $user = User::update($validated);
}

Additionally it can get a bit messy if you are adding conditional checks if you are making the request with AJAX. AJAX requests should respond with a json body and a HTTP response code, and normal requests will respond with a redirect.

I would separate your AJAX requests into separate methods again, and these can be prefixed with api

so

Standard:

  • POST /your-controller - hits YourController::store
  • PATCH /your-controller - hits YourController::update

Ajax

  • POST /api/your-controller - hits API/YourController::store
  • PATCH /api/your-controller - hits API/YourController::update

This may seem like overkill but what you'll end up with is 4 very small easy to understand methods, rather than 1 with a load of if statements in it.

1 like
afoysal's avatar

Thanks @automica . What is the difference between 'email' => 'required|email|unique:users,email,' . $request->user_id, and 'email' => 'required|email|unique:users', ? Thanks.

automica's avatar

@afoysal the first ensures its unique check doesn't include the email address of the user who is updating their account.

For example, if i'm already registered as a user, and I supply my email address as part of an update object, then I don't want the validator to prevent me using my existing email.

BTW for the Create part, you wouldn't need to check the $request->user_id as theres no user set yet.

    $request->validate([
        'name' => 'required',
        'email' => 'required|email|unique:users,email',
        'password' => 'required',
        'role' => 'required',
    ]);
marcosdipaolo's avatar

Yet, this does not answer the question, how to deal with passwords when using updateOrCreate. My guess is method should get 3 args, identifier, create array, and update array.

Kortez12's avatar

@marcosdipaolo Don't use createOrUpdate in this scenario. First, find the user by ID. If the user exists, update only the selected columns (unset the password column if you don't want to update it). If the user does not exist, create a new user.

rdelorier's avatar

@marcosdipaolo Make a new post, this is 4 years old. Laravel is as V12 now, it's not the same. Either look at the codebase or start a new thread.

The method should get 2 args: the search, and the supplementals if it does not exist.

unohuim's avatar

Maybe I'm doing it wrong, but I always do Model::findOrNew(['id'=>$user->id) and then check if it's null. If not, then I do the $user->email = etc etc aftewards.

Snapey's avatar

I use the same method for both. This is because I pass an empty model into the update method

like


public function create($request)
{
	$user = new User;

	return $this->update($request, $user)
}

public function update($request User $user)
{
	// validate your fields here

	$user->fill($request->validated());

	$user->save();

	return back();
}

ps. don't make the password 'required' if you don't want it updating. I will always have a separate route and controller for changing the password, because of course you should also check the existing password is validated before setting a new one.

Please or to participate in this conversation.