我有一个包含以下字段的餐厅表
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();
}