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

ahmedde's avatar

Model Accessors ignore mergeWhen condition and executes

Hi there,

I have this UserResource for my REST API:

/**
 * @mixin \App\Models\User
 */
class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'type' => 'user',
            'attributes' => [
                'name' => $this->name,
                'email' => $this->email,
                $this->mergeWhen($this->relationLoaded('latestSubscription'), [
                    'subscriptionStatus' => $this->subscription_status,
                ]),

This is how the attribute is defined:

/**
 * Get the user's subscription status.
 */
protected function subscriptionStatus(): Attribute
{
    \Log::debug('subscription_status is called');

    return Attribute::make(
        function () {
            if ($this->hasPermissionTo(Permissions::GOLDEN_PASS)) {
                return SubscriptionStatusEnum::GOLDEN_PASS->value;
            }

            if (! $this->relationLoaded('latestSubscription')) {
                return null;
            }

            return $this->latestSubscription->status ?? SubscriptionStatusEnum::PROSPECT->value;
        }
    );
}

Problem: subscription_status attribute is fired, and the queries inside are made (hasPermissionTo) even though the relationship is not loaded, and i get "subscription_status is called" in my logs. I thought mergeWhen will not execute the callback unless the first condition is false, and it is false (given that "subscriptionStatus" is never returned in the response.

Am I misunderstanding what mergeWhen does, and is there an alternative that does what I want?

Thanks

0 likes
1 reply

Please or to participate in this conversation.