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

Laravel中如何将活动日志存到MongoDB?遇prepare()调用空对象错误

问题解决:spatie/laravel-activitylog 结合 MongoDB 存储日志报错处理

问题根源

  1. spatie/laravel-activitylog 默认的 Activity 模型基于 MySQL 的 Eloquent 实现,直接指定 MongoDB 连接会导致与 MongoDB 驱动不兼容,触发 Call to a member function prepare() on null 错误。
  2. 你的 User 模型错误继承了 MongoDB 版本的 Authenticatable,这会强制 User 数据存储到 MongoDB,违背了「User 存 MySQL」的需求。

解决方案步骤

1. 修正 User 模型(确保数据存 MySQL)

将 User 模型改回继承原生 Laravel 的 Authenticatable,并指定 MySQL 连接(若默认连接已是 MySQL 可省略):

<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class User extends Authenticatable implements MustVerifyEmail
{
    use LogsActivity;

    // 指定使用 MySQL 连接(可选,默认连接为 MySQL 时可删除)
    protected $connection = 'mysql';

    protected $fillable = [
        'name', 'email', 'password', // 根据实际业务补充字段
    ];

    // 按需补充 hidden、cast 等属性

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults();
    }
}

2. 创建 MongoDB 版自定义 Activity 模型

在 app/Models 目录下新建 MongoActivity.php,继承 Jenssegers 的 MongoDB 模型并实现 spatie 的 Activity 接口:

<?php
namespace App\Models;

use Jenssegers\Mongodb\Eloquent\Model;
use Spatie\Activitylog\Contracts\Activity;

class MongoActivity extends Model implements Activity
{
    // 指定使用 MongoDB 连接
    protected $connection = 'mongodb';

    // MongoDB 主键配置
    protected $primaryKey = '_id';
    protected $keyType = 'string';
    public $incrementing = false;

    // 对应 MongoDB 集合名
    protected $collection = 'activities';

    // 允许批量赋值的字段
    protected $fillable = [
        'log_name',
        'description',
        'subject_id',
        'subject_type',
        'causer_id',
        'causer_type',
        'properties',
        'batch_uuid',
    ];

    // 字段类型转换
    protected $casts = [
        'properties' => 'array',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    // 实现 ActivityInterface 接口方法
    public function getLogName(): string
    {
        return $this->log_name;
    }

    public function getDescription(): string
    {
        return $this->description;
    }

    public function getSubject()
    {
        if (! $this->subject_type || ! $this->subject_id) {
            return null;
        }
        return app($this->subject_type)->find($this->subject_id);
    }

    public function getCauser()
    {
        if (! $this->causer_type || ! $this->causer_id) {
            return null;
        }
        return app($this->causer_type)->find($this->causer_id);
    }

    public function getProperties(): array
    {
        return $this->properties;
    }

    public function getBatchUuid(): ?string
    {
        return $this->batch_uuid;
    }
}

3. 修改 activitylog 配置,指定自定义模型

打开 config/activitylog.php,将默认的 Activity 模型替换为刚创建的 MongoActivity:

// 原配置
// 'activity_model' => Spatie\Activitylog\Models\Activity::class,

// 修改为
'activity_model' => App\Models\MongoActivity::class,

确认数据库连接配置保留原有设置:

'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'),

4. 初始化 MongoDB 集合

MongoDB 无需传统迁移,可手动创建 activities 集合,或通过迁移生成:

  1. 创建 MongoDB 迁移文件:
php artisan make:migration create_activities_collection --connection=mongodb
  1. 编写迁移内容:
<?php

use Illuminate\Database\Migrations\Migration;
use Jenssegers\Mongodb\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::connection('mongodb')->create('activities', function (Blueprint $table) {
            $table->string('_id')->primary();
            $table->string('log_name');
            $table->text('description');
            $table->nullableMorphs('subject');
            $table->nullableMorphs('causer');
            $table->json('properties');
            $table->string('batch_uuid')->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::connection('mongodb')->dropIfExists('activities');
    }
};
  1. 运行迁移:
php artisan migrate --connection=mongodb

5. 清除配置缓存

确保新配置生效:

php artisan config:clear

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:50:29