如何为具有多种类型事件的日志设置Laravel多态关系

omqzjyyz  于 2022-12-14  发布在  其他
关注(0)|答案(1)|浏览(99)

我有一个应用程序,我需要在其中存储可能具有多种类型的一对多关系。
这个用例是一个log模型,它有多个events。但是event可以是多种类型,比如transitiondecisionmessage。我想我可能想在这里使用多态关系,但是我不知道如何在模型和数据库中设置它。
任何指针从任何人谁做了类似的将是可怕的!TIA!
当前模型布局:

Application
+ id
+ name

-----

Log
+ id
+ application_id
+ {others}

-----

Transition (similar format for other event types)
+ id
+ from
+ to
+ {others}

public function eventable() {
    return $this->morphTo();
}

我所尝试的

Event
+ id
+ name

-----

Eventables
+ event_id
+ eventable_id
+ eventable_type

当我接着试

$log = Log::create([
            'id' => Str::uuid(),
            'application_id' =>1,
            'service' => 'Service',
            'source' => 'Source',
            'timestamp' => Carbon::now()->setTimezone('Europe/London')->format('Y-m-d H:i:s.v'),
            'appid' => 'appid',
            'traceid' => 'traceid',
            'requestid' => 'requestid',
            'sessionid' => 'sessionid',
            'locale' => 'locale',
            'seqid' => 1,
            'partition' => 1,
            'offset' => 0,
            'request' => 'request',
            'response' => 'response',
            'data' =>  'data',
        ]);

        $event = Transition::create([
            'from' => 'from',
            'from_name' => 'from_name',
            'from_type' => 'from_type',
            'to' => 'to',
            'to_name' => 'to_name',
            'to_type' => 'to_type',
        ]);

        $event2 = Transition::create([
            'from' => 'from',
            'from_name' => 'from_name',
            'from_type' => 'from_type',
            'to' => 'to',
            'to_name' => 'to_name',
            'to_type' => 'to_type',
        ]);

        $log->events()->saveMany([
            $event, $event2
        ]);

我得到

Column not found: 1054 Unknown column 'eventable_id' in 'field list' (SQL: update `transitions` set `eventable_id` = 3cc1308e-7539-43ee-8296-15fe5e317c6a, `eventable_type` = App\Models\Log, `transitions`.`updated_at` = 2022-12-05 15:53:02 where `id` = 19)
esyap4oy

esyap4oy1#

如果你想使用一个关系函数,你不能在一个常量类型的模型和许多不同类型的模型之间建立多态关系,你需要一个具有一对一多态关系的中间模型。
为此,您需要3种类型的表。

  • 日志表(包括ID、应用程序ID、服务等列)
  • “事件”表(包括标识、事件标识、事件表标识、事件表类型)
  • 多个“Eventable”表- Transition、Decision、Message等(除了存储数据所需的列外,这些表不需要任何特殊列)

您的Logs模型看起来如下所示:

public class Log extends Model{
    public function events(){
        return $this->hasMany(Event::class);
    }
}

Events类如下所示

public class Event extends Model{
    public function eventable(){
        return $this->mprphTo();
    }
    public function log(){
        return $this->belongsTo(Log::class);
    }
}

Transition类将如下所示

public class Transition extends Model{
    public function comments()
    {
        return $this->morphOne(Event::class, 'eventable');
    }
}

要加载任何事件对象,首先要加载事件关系,然后查询每个Event对象上的事件关系。通过使用$logsQuery->with('events.eventable')进行早期加载,可以减少查询次数。
如果您需要每个事件对象都与Logs模型有直接关系,我能想到的唯一解决方案就是拥有单独的转换、决策和消息关系。

相关问题