简体   繁体   中英

Laravel - Relationships issue

I have 3 models:

class Site extends Model
{
    public function users()
    {
        return $this->belongsToMany('App\Models\User');
    }
    public function stats()
    {
        return $this->hasMany('App\Models\Stat');
    }
}

class User extends Model
{
    public function sites()
    {
        return $this->belongsToMany('App\Models\Site');
    }
    public function stats()
    {
        return $this->belongsToMany('App\Models\Stat');
    }
}

class Stat extends Model
{

    public function users()
    {
        return $this->belongsToMany('App\Models\User');
    }
    public function sites()
    {
        return $this->belongsTo('App\Models\Site');
    }
}

So there are :

  • a many to many relation between sites and users
  • a many to many relation between users and stats
  • a one to many relation between site and stats

A site have a list of stats and from this list, an user can have some stats.

在此输入图像描述

I'm trying to get all sites and foreach site, count of stats for the connected user.

For the moment i tried :

//repository
function getAll($user_id = 0)
{

    $with = [];

    $with['users'] = function ($query) use ($user_id) {
        $query->where('id', '=', $user_id);
    };
    return Site::with($with)->orderBy('name')->get();
}
//controller
$sites = getAll($user_id);

//view
foreach($sites as $site){
  $count_stats = $site->users->first()->stats->where('site_id',$site->id)->count();
}

It works but it is not very elegant, it does a lot of sql requests and the page is slower.

Do you have a better solution ?

If Sites have many Users, and Sites have many Stats, then a User has many Stats through Site

Modify User class:

public function stats() {
    return $this->hasManyThrough('App\Stat', 'App\Site', 'user_id', 'site_id');
}

Eager load:

$user = User::with('stats')->find($user_id);
$stats = $user->stats();

Also, I think your Stat should belongsTo Site, since Site hasMany Stat. You need to change a lot of the belongsToMany as well since they look incorrectly used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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