mtvs/eloquent-aggregate-rating

该包最新版本(v2.0.0)没有可用的许可信息。

针对Laravel Eloquent模型和评论的自动评级聚合

v2.0.0 2021-01-21 15:11 UTC

This package is auto-updated.

Last update: 2024-09-24 15:35:32 UTC


README

针对Laravel Eloquent模型和评论的自动评级聚合。

Build Status

此包聚合了被评论的模型的平均评分和评分数量,并在发生指定的事件时更新模型,例如:在保存或删除评论后。因此,它简化了访问这些值的操作,并在检索具有聚合评分值的模型列表时消除了n+1查询的问题,同时也消除了根据评分对模型进行排序时需要子查询的需求。

设置

首先,修改被评论的模型的数据表,并添加两个新列,一个用于存储评分的平均值,另一个用于存储评分的数量,例如

	$table->float('rating_average')->nullable();
	$table->unsignedInteger('rating_count')->default(0);

显然,评论表中必须有rating列。

然后,有两个特质。一个是用于被评论的模型的。它包含一个必须实现以返回到评论模型关系的抽象方法。

use AggregateRating\HasAggregateRating;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany

Class Item extends Model
{
	use HasAggregateRating;

	public function aggregateRatingReviews(): HasMany
	{
		return $this->reviews();
	}

	// ...
}

另一个是用于评论模型的。它包含一个返回到被评论模型关系的抽象方法。

use AggregateRating\HasIndividualRating;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

Class Review extends Model
{
	use HasIndividualRating;

	public function aggregateRatingItem(): BelongsTo
	{
		return $this->item();
	}

	// ...
}

触发事件

位于HasIndividualRating特质上的aggregateRatingEvents()返回触发聚合和更新相关模型过程的评论模型上的事件。此方法的默认定义如下

	/**
     * Return the model events that require updating the aggregate rating.
     *
     * @return array
     */
	protected static function aggregateRatingEvents()
	{ 
		return [
			'saved', 'deleted',
		];
	}

但你可以覆盖它来指定自定义事件

	/**
     * Return the model events that require updating the aggregate rating.
     *
     * @return array
     */
	protected static function aggregateRatingEvents()
	{ 
		return [
			'approved', 'suspended', 'rejected', 'deleted',
		];
	}

自定义列名

如果你想为你的列选择其他名称,将以下常量设置在您的模型上为相应的值。

use AggregateRating\HasAggregateRating;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany

Class Item extends Model
{
	use HasAggregateRating;

	const RATING_AVERAGE = 'rating_average';
	const RATING_COUNT = 'rating_count';

	public function aggregateRatingReviews(): HasMany
	{
		return $this->reviews();
	}

	// ...
}
use AggregateRating\HasIndividualRating;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

Class Review extends Model
{
	use HasIndividualRating;

	const RATING = 'rating';

	public function aggregateRatingItem(): BelongsTo
	{
		return $this->item();
	}

	// ...
}