简体   繁体   English

在laravel查询中与关系堆栈

[英]Stack at laravel query with relation

I need your help. 我需要你的帮助。 I have this query but I am getting trouble 我有此查询,但我遇到了麻烦

I have these two tables: 我有这两个表:

users
---------------------
 id | name | surname
---------------------

users_ratings 
-------------------------------------
 id | user_id | customer_id | rating
-------------------------------------

Not every user has a rating. 并非每个用户都有评分。

I am trying to show on a view in Laravel every user and it's rating. 我试图在Laravel的视图上显示每个用户及其等级。

$users=User::where('role','=','4')->paginate(8);
$data = array();
foreach ($users as $user)
{
    $ratings = UserRating::where('user_id', $user->id)->get();
    $nr = UserRating::where('user_id',  $user->id)->count();
    $sum = 0;


        foreach ($ratings as $rate) {
            if ($rate->rating != "") {
                $rating = $rate->rating;
                $sum = $sum + $rating;

            }
        }

        if ($nr == 0) {
            $avg = 0;
        } else {
            $avg = ($sum / $nr);
        }

    }
    else {

        $avg=0;
    }
        $object = [
            'id' => $user->id,
            'rating' => number_format($avg, 3, '.', ','),
            'user'=>$user
        ];

        array_push($data, $object);

       return view('pages.users', ['data' => $data]);

Now I am showing in view: 现在,我在视图中显示:

@foreach($data as $d)
    {{$d->id}}
    {{$d->rating}]
    {{$d->user->name}}
@endforeach

I know that something is wrong here. 我知道这里有些问题。 It shows 表明

"Trying to get property 'id' of non-object.... “试图获取非对象的属性'id'。

You should try this: 您应该尝试这样:

@foreach($data as $d)
{{$d['id']}}
{{$d['rating']}}

@endforeach

OR 要么

@foreach($data as $key => $d)
    {{$d[$key]->id}}
    {{$d[$key]->rating}]
    {{$d[$key]->user->name}}
@endforeach

Updated Answer 更新的答案

@foreach($data as $key => $d)
  @foreach($d as $rsltDetails)
    {{$rsltDetails['id']}}
    {{$rsltDetails['rating']}}
  @endforeach
@endforeach

There are many things wrong here. 这里有很多错误。

First, you have an n+1 query. 首先,您有一个n + 1查询。 You are fetching the users and inside the loop for each user, you are performing 2 additional queries. 您正在获取用户,并且在每个用户的循环内,您还要执行2个附加查询。

$users = User::where('role','=','4')->paginate(8);

foreach ($users as $user) {
    $ratings = UserRating::where('user_id', $user->id)->get();
    $nr = UserRating::where('user_id',  $user->id)->count();
    $sum = 0;
    ...
}

Solution: 解:

This code will execute only two queries. 此代码将仅执行两个查询。

// I am assuming the relation name between User and UserRating is ratings
$users = User::with('ratings')->where('role','=','4')->paginate(8);

return view('pages.users', compact('users));

In your view, you can easily print the values 在您看来,您可以轻松打印值

@foreach($users as $user)
    {{ $user->id }}
    {{ number_format($user->ratings->avg('rating'), 3, '.', ',') }}
    {{ user->name }}
@endforeach

Doing it that way is not a scalable solution and you will face the N+1 problem. 这样做不是可扩展的解决方案,您将面临N + 1问题。 I would suggest the following. 我建议以下。

First, in your App\\User model, define your relationship with App\\UserRating : 首先,在您的App\\User模型中,定义您与App\\UserRating关系:

use App\UserRating; 

public function ratings()
{
    return $this->hasMany(UserRating::class); 
}

Then, define your inverse relationship in App\\UserRating 然后,在App\\UserRating定义逆关系

use App\User; 

public function user()
{
    return $this->belongsTo(User::class);
}

Finally, you could simplify your loop like this: 最后,您可以像这样简化循环:

$users = User::where('role','=','4')
    ->with('ratings') // eager-load ratings
    ->paginate(8);

$results = []; 

foreach($users as $user) {
    // To access ratings you would do 
    // foreach($user->ratings as $rating) { }

    // To get the count you would do 
    // $user->ratings->count(); 
}

In your blade file, you could just do this: 在刀片文件中,您可以执行以下操作:

@foreach($users as $user)
    {{ $user->id }}
    {{ number_format($user->ratings->avg('rating'), 3, '.', ',') }}
@endforeach

Doing it this way will solve your N+1 problem and leverages Laravel's Collections to make everything a little bit cleaner as well :) 这样做可以解决您的N + 1问题,并利用Laravel的Collections来使一切变得更干净:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM