Skip to content

Issue with automaticallyEagerLoadRelationships() and withDefault() – Related Model Created with Missing Foreign Keys #55744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
veneliniliev opened this issue May 15, 2025 · 1 comment

Comments

@veneliniliev
Copy link
Contributor

Laravel Version

12.14.1

PHP Version

8.4

Database Driver & Version

No response

Description

When using Model::automaticallyEagerLoadRelationships() in combination with a relationship that uses withDefault() (for example, a morphOne wallet relationship), accessing the relationship in an Eloquent event like created or saved leads to Laravel returning a default (unsaved) related model. If you try to save this model (for instance, to initialize some data), it may be persisted without proper foreign key values, resulting in an integrity constraint violation (e.g., is null). holder_id
This is unintuitive and can easily cause hard-to-trace bugs in codebases that rely on eager loading and relationship defaults.

Example

Business Model:

class Business extends Model
{
    public static function booted()
    {
        static::automaticallyEagerLoadRelationships();
    }

    public function wallet()
    {
        return $this->morphOne(Wallet::class, 'holder')
            ->withDefault([
                'balance' => 0,
            ]);
    }
}

Wallet Model:

class Wallet extends Model
{
    public function holder()
    {
        return $this->morphTo();
    }
}

In BusinessObserver:

public function created(Business $business)
{
    // Access wallet and try to save it
    $business->wallet->updateBalance();
    // ...other logic
}

Result:

If the business does not have a wallet yet, $business->wallet returns the default wallet (not saved, belonging to the business). If you try to call $business->wallet->save() (possibly via updateBalance()), Laravel attempts to insert it, but and are null, which causes: holder_id``holder_type

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'holder_id' cannot be null

Expected Behavior

Related models returned by withDefault() should not be saved automatically unless all their required foreign keys are present. Alternatively, using automatic eager loading should not trigger the creation of a default related model that is not ready to be persisted.

Note:
When Model::automaticallyEagerLoadRelationships() is not used, the relationship with withDefault() works as expected and no integrity constraint violations occur.

Steps To Reproduce

  1. Enable in your model. automaticallyEagerLoadRelationships
  2. Define a relationship with withDefault.
  3. Within a model event, access and attempt to use/save the related model.
  4. Observe the failure if the related model was not created before the event handler.
Copy link

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants