在laravel查询中与关系堆栈

时间:2019-01-10 10:19:05

标签: php laravel

我需要你的帮助。 我有此查询,但遇到麻烦了

我有这两个表:

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

users_ratings 
-------------------------------------
 id | user_id | customer_id | 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]);

现在我在视野中显示:

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

我知道这里有些问题。它显示了

  

“试图获取非对象的属性'id'。...

3 个答案:

答案 0 :(得分:1)

您应该尝试以下操作:

@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

更新后的答案

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

答案 1 :(得分:1)

这里有很多错误。

首先,您有一个n + 1查询。您正在获取用户,并且在每个用户的循环内,您还要执行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;
    ...
}

解决方案:

此代码将仅执行两个查询。

// 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));

在您看来,您可以轻松打印值

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

答案 2 :(得分:0)

以这种方式进行操作不是可扩展的解决方案,您将面临N+1问题。 我建议以下。

首先,在您的App\User模型中,定义您与App\UserRating的关系:

use App\UserRating; 

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

然后,在App\UserRating中定义逆关系

use App\User; 

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

最后,您可以像这样简化循环:

$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(); 
}

在刀片文件中,您可以这样做:

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

通过这种方式可以解决您的N + 1问题,并利用Laravel的Collections来使一切变得更干净:)