Skip to content

Bug Report: updateOrCreate() applies global scopes when finding, but ignores them when updating #55253

@Sairahcaz

Description

@Sairahcaz

Laravel Version

11.43.2

PHP Version

8.2.28

Database Driver & Version

mysql Ver 8.0.36 for macos14 on arm64 (MySQL Community Server - GPL)

Description

The updateOrCreate() method behaves inconsistently with regard to global scopes in Laravel:

  • When finding the model via firstOrNew(), global scopes are applied.
  • When updating the existing model via $model->save(), the resulting UPDATE query does not include any global scope constraints.

This inconsistency is particularly problematic in multi-tenant applications where global scopes are used to enforce tenant isolation (e.g. team_id, organization_id).

Expected Behavior
The UPDATE query should respect global scopes, just like the SELECT query does.

Thanks again for all the amazing work on Laravel!

Steps To Reproduce

1. Define a global scope on team_id:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected static function booted(): void
    {
        static::addGlobalScope('team', function (Builder $builder) {
            if (auth()->check()) {
                $builder->where('team_id', auth()->user()->team_id);
            }
        });
    }
}

2. Call updateOrCreate() on an existing record:

Flight::updateOrCreate(
    ['id' => 123], // Existing record with team_id = 1
    ['status' => 'delayed']
);

3. Observe the SQL queries:

-- SELECT query (correctly scoped):
SELECT * FROM flights WHERE id = 123 AND team_id = 1 LIMIT 1;

-- UPDATE query (missing scope!):
UPDATE flights SET status = 'delayed' WHERE id = 123;
-- ⚠️ Missing team_id = 1 in the WHERE clause

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions