diff --git a/src/Jobs/RecordMetric.php b/src/Jobs/RecordMetric.php index 1ffa270..9e0053a 100644 --- a/src/Jobs/RecordMetric.php +++ b/src/Jobs/RecordMetric.php @@ -39,7 +39,7 @@ public function handle(): void ); /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new DatabaseMetricManager::$model; + $model = transform($metric->model() ?? DatabaseMetricManager::$model, fn (string $model) => new $model); $model->getConnection()->transaction(function () use ($metric, $value, $model) { $instance = $model->newQuery()->firstOrCreate([ diff --git a/src/JsonMeasurableEncoder.php b/src/JsonMeasurableEncoder.php index 22f6f5a..de97733 100644 --- a/src/JsonMeasurableEncoder.php +++ b/src/JsonMeasurableEncoder.php @@ -12,7 +12,7 @@ class JsonMeasurableEncoder implements MeasurableEncoder */ public function encode(Measurable $metric): string { - $model = $metric->measurable(); + $measurable = $metric->measurable(); return json_encode([ 'name' => Enum::value($metric->name()), @@ -21,9 +21,10 @@ public function encode(Measurable $metric): string 'month' => $metric->month(), 'day' => $metric->day(), 'hour' => $metric->hour(), - 'measurable' => $model ? get_class($model) : null, - 'measurable_key' => $model?->getKeyName() ?? null, - 'measurable_id' => $model?->getKey() ?? null, + 'model' => $metric->model(), + 'measurable' => $measurable ? get_class($measurable) : null, + 'measurable_key' => $measurable?->getKeyName() ?? null, + 'measurable_id' => $measurable?->getKey() ?? null, 'additional' => $metric->additional(), ]); } @@ -36,12 +37,12 @@ public function decode(string $key, int $value): Measurable $attributes = json_decode($key, true); if ($attributes['measurable'] && class_exists($attributes['measurable'])) { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = (new $attributes['measurable'])->newFromBuilder([ + /** @var \Illuminate\Database\Eloquent\Model $measurable */ + $measurable = (new $attributes['measurable'])->newFromBuilder([ $attributes['measurable_key'] => $attributes['measurable_id'], ]); } else { - $model = null; + $measurable = null; } $date = CarbonImmutable::create( @@ -56,9 +57,10 @@ public function decode(string $key, int $value): Measurable category: $attributes['category'], value: $value, date: $date, - measurable: $model, + measurable: $measurable, additional: $attributes['additional'] ?? [], hourly: $attributes['hour'] ?? false, + model: $attributes['model'] ?? null, ); } } diff --git a/src/Measurable.php b/src/Measurable.php index ab8cbad..f379128 100644 --- a/src/Measurable.php +++ b/src/Measurable.php @@ -42,6 +42,11 @@ public function day(): int; */ public function hour(): ?int; + /** + * Get the model class of the metric. + */ + public function model(): ?string; + /** * Get the measurable model of the metric. */ diff --git a/src/MetricData.php b/src/MetricData.php index f8885a2..f6fe7a0 100644 --- a/src/MetricData.php +++ b/src/MetricData.php @@ -23,6 +23,7 @@ public function __construct( protected ?Model $measurable = null, protected array $additional = [], protected bool $hourly = false, + protected ?string $model = null, ) { $this->date ??= new CarbonImmutable; } @@ -83,6 +84,14 @@ public function hour(): ?int return $this->hourly ? $this->date->hour : null; } + /** + * {@inheritDoc} + */ + public function model(): ?string + { + return $this->model; + } + /** * {@inheritDoc} */ diff --git a/src/PendingMetric.php b/src/PendingMetric.php index 0b28ea0..72bbf50 100644 --- a/src/PendingMetric.php +++ b/src/PendingMetric.php @@ -28,6 +28,11 @@ class PendingMetric */ protected ?Model $measurable = null; + /** + * The model to use for the metric. + */ + protected ?string $model = null; + /** * Whether to track hourly metrics. */ @@ -86,6 +91,16 @@ public function measurable(Model $measurable): self return $this; } + /** + * Set the metric model to use. + */ + public function model(string $model): self + { + $this->model = $model; + + return $this; + } + /** * Enable hourly tracking for the metric. */ @@ -130,7 +145,8 @@ public function toMetricData(int $value): Measurable $this->date, $this->measurable, $this->additional, - $this->trackHourly + $this->trackHourly, + $this->model, ); } } diff --git a/tests/PendingMetricTest.php b/tests/PendingMetricTest.php index 6cc6881..6094a3d 100644 --- a/tests/PendingMetricTest.php +++ b/tests/PendingMetricTest.php @@ -42,6 +42,14 @@ ->and($data->day())->toBe($date->day); }); +it('can set model', function () { + $pending = PendingMetric::make('page_views')->model('CustomMetric'); + + $data = $pending->toMetricData(1); + + expect($data->model())->toBe('CustomMetric'); +}); + it('can set measurable', function () { $user = createUser();