Luu*_*gen 7 php mysql relationship laravel eloquent
我有三张桌子:
products: id|name|description|slug|category_id|...
reviews: id|product_id|review_text|name|email|...
review_rows id|review_id|criteria|rating
Run Code Online (Sandbox Code Playgroud)
审查表存储审阅文本,审阅的编写者并具有外部product_id密钥.review_rows表存储不同标准的评级,例如:
----------------------------------------
| id | criteria | rating | review_id |
----------------------------------------
| 1 | price | 9 | 12 |
----------------------------------------
| 2 | service | 8 | 12 |
----------------------------------------
| 3 | price | 6 | 54 |
----------------------------------------
| 4 | service | 10 | 54 |
----------------------------------------
Run Code Online (Sandbox Code Playgroud)
审核行使用review_id外键链接到审阅表.我已经建立了这样的模型关系:
Product -> hasMany -> Review
Review -> belongsTo -> Product
Review -> hasMany -> ReviewRow
ReviewRow -> belongsTo -> Review
Run Code Online (Sandbox Code Playgroud)
现在,我想在我的类别和产品页面上显示产品的平均评分.我怎样才能做到这一点?
我需要对每次审核的所有评论进行求和并对其进行平均,然后对每个评论的所有评分进行求和并平均,最后得出该产品的总评分.这可能是通过Eloquent还是我需要不同的解决方案或不同的数据库设计/结构?
提前致谢!
Jar*_*zyk 16
你需要这样的东西http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently/只是略微调整以满足你的需求:
public function reviewRows()
{
return $this->hasManyThrough('ReviewRow', 'Review');
}
public function avgRating()
{
return $this->reviewRows()
->selectRaw('avg(rating) as aggregate, product_id')
->groupBy('product_id');
}
public function getAvgRatingAttribute()
{
if ( ! array_key_exists('avgRating', $this->relations)) {
$this->load('avgRating');
}
$relation = $this->getRelation('avgRating')->first();
return ($relation) ? $relation->aggregate : null;
}
Run Code Online (Sandbox Code Playgroud)
然后就这么简单:
// eager loading
$products = Product::with('avgRating')->get();
$products->first()->avgRating; // '82.200' | null
// lazy loading via dynamic property
$product = Product::first()
$product->avgRating; // '82.200' | null
Run Code Online (Sandbox Code Playgroud)