计算拉拉维尔的平均餐厅评分



我有一个包含以下字段的餐厅表

Schema::create('restaurants', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
            $table->string('name');
            $table->text('menu');
            $table->string('hours');
            $table->string('contact');
            $table->string('payment');

包括我稍后添加的存储平均评级rating_count

[我有一个评论表,存储每个餐厅的评级]

https://i.stack.imgur.com/MXudX.png我想计算每家餐厅的平均评分,并将其显示为数字在餐厅视图中

最好在

餐厅模型中尽可能轻松地定义关系的方法。

public function reviews() {
    return $this->hasMany('AppReview');
}

现在您可以使用此关系来获取速率,您可以将模型中不是列的属性添加为追加属性。

protected $appends = ['rate'];

然后有一个函数来分配值:

public functions getRateAttribute() {
     return $this->reviews->avg('rate') ?? 0;
}

这样做的问题是,顾名思义,追加的属性总是附加到模型的实例中。

因此,如果您只是执行以下操作:

$restaurant= Restaurant::first();

即使您不需要费率,laravel仍然会为您准备好$restaurant->rate,因此它将执行平均查询。

也是拉拉维尔avg('column_name')的提醒:

  • 当不存在数据时,它给出空
  • 如果您平均非数字列,它给出的值类似于 0.0
  • 如果存在超过 2 个小数点(主要是 4 个(的值,则以 3.9265 格式给出有效值
您需要在

餐厅模型中设置关系,如下所示:

public function reviews()
{
    return $this->hasMany(Review::class);
}

然后要计算评级,您可以添加另一种方法:

public function rating()
{
    $totalReviews = $this->reviews->count();
    if($totalReviews)
    {
        $totalRating = $this->reviews->sum('rating');
        return number_format($totalRating / $totalReviews, 1);
    }
    return 0;
}

然后使用它:

$restaurant = Restaurant::find(1)->with('reviews');
$restaurant->rating(); // should give you what you need.

--编辑

在餐厅模型中添加如下所示的访问器:

protected $appends = ['rating_count'];
public function getRatingCountAttribute()
{
    return $this->reviews->avg('rating');
}

然后使用它:

$restaurant->rating_count;

拿出所有餐馆的评论。

$restaurants = Restaurants::with('reviews')->get();

循环遍历餐厅并使用收集方法平均值来计算字段。

foreach ($restaurants as $restaurant) {
    $restaurant->rating_count = $restaurant->reviews->avg('rating');
    $restaurant->save();
} 

最新更新