You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel透视表工厂报错:Call to a member function __call() on null

问题分析与解决

错误Call to a member function __call() on null出现在调用OrderProduct::factory()->create()时,核心原因是OrderProduct工厂未正确关联对应模型,或OrderProduct模型未正确创建/配置。

1. 确保OrderProduct模型存在并配置正确

在app/Models/目录下创建(或检查)OrderProduct.php,确保填充字段和表名正确:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class OrderProduct extends Model
{
    // 允许批量赋值的字段
    protected $fillable = ['order_id', 'product_id', 'quantity', 'price'];

    // 如果你的透视表名不是默认的`order_products`(比如是`order_product`),需手动指定
    // protected $table = 'order_product';
}

2. 修复OrderProductFactory的模型绑定

打开Database/Factories/OrderProductFactory.php,必须指定对应的模型类:

<?php

namespace Database\Factories;

use App\Models\OrderProduct;
use Illuminate\Database\Eloquent\Factories\Factory;

class OrderProductFactory extends Factory
{
    // 关键:绑定对应的模型
    protected $model = OrderProduct::class;

    public function definition(): array
    {
        return [
            'order_id' => \App\Models\Order::factory(),
            'product_id' => \App\Models\Product::factory(),
            'quantity' => $this->faker->numberBetween(1, 10),
            'price' => $this->faker->randomFloat(2, 5, 100),
        ];
    }
}

3. 确认Order与Product模型的多对多关联配置

因为透视表包含额外字段(quantity、price),需要在关联中指定使用OrderProduct模型并声明这些字段:

Order模型:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    // ...其他代码

    public function products()
    {
        return $this->belongsToMany(Product::class)
            ->using(OrderProduct::class)
            ->withPivot('quantity', 'price');
    }
}

Product模型:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    // ...其他代码

    public function orders()
    {
        return $this->belongsToMany(Order::class)
            ->using(OrderProduct::class)
            ->withPivot('quantity', 'price');
    }
}

4. 简化测试代码(可选优化)

你可以利用Eloquent关联直接创建关联数据,无需手动构造OrderProduct数据:

public function testCalculateOrderTotal(): void
{
    $address = Address::factory()->create();
    $client = Client::factory()->create(['address_id' => $address->id]);
    $order = Order::factory()->create(['client_id' => $client->id]);
    
    // 通过关联创建带额外字段的透视表数据
    $order->products()->attach([
        Product::factory()->create()->id => ['quantity' => 2, 'price' => 100.00],
        Product::factory()->create()->id => ['quantity' => 1, 'price' => 150.00],
    ]);

    $orderProducts = $order->products->map(fn($product) => $product->pivot);

    $this->orderProductRepository
        ->shouldReceive('findByOrder')
        ->with($order->id)
        ->once()
        ->andReturn(collect($orderProducts));

    $expectedTotal = (2 * 100.00) + (1 * 150.00);
    $total = $this->orderProductService->calculateOrderTotal($order->id);

    $this->assertIsFloat($total);
    $this->assertEquals($expectedTotal, $total);
}

做完以上步骤后,重新执行测试命令即可解决报错。

内容的提问来源于stack exchange,提问作者barbgluz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:13:21