Laravel 5.2 Eloquent - 通过多对多关系建立模型

时间:2016-08-14 15:10:05

标签: laravel eloquent many-to-many

我有3个模型:环境,网站和突发事件。每个都有各自的表格。

我的模型关系定义如下:

环境有很多站点(站点表中environment_id

public function sites()
{ 
   return $this->hasMany('App\Site');
}

站点属于环境(站点表中的environment_id),属于许多突发事件(带有incident_idsite_id的incident_site关系表)

public function environment()
{
    return $this->belongsTo('App\Environment');
}

public function incidents()
{
    return $this->belongsToMany('App\Incident');
}

事件属于多个网站(带incident_idsite_id的事件_用户关系表)

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

问题:我正在尝试通过环境模型检索所有网站突发事件的集合,如下所示:

$environment->incidents()->count();

到目前为止,我能够让它在控制器中工作的唯一方法就是:

    $environment->load(['sites.incidents' => function ($q) use ( &$incidents ) {
       $incidents = $q->orderBy('id','desc')->get();
    }]);

但是在App的其他领域工作并不理想。

问题:如何通过环境模型中的方法使上述关系工作?有更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

在多对多关系中没有任何使用hasManyThrough()的规定。但是您可以使用DB::raw()来实现此目的,或者您可以将以下函数添加到您的BaseModel中,如forum中所示。

public function manyThroughMany($related, $through, $firstKey, $secondKey, $pivotKey)
   {
       $model = new $related;
       $table = $model->getTable();
       $throughModel = new $through;
       $pivot = $throughModel->getTable();

       return $model
           ->join($pivot, $pivot . '.' . $pivotKey, '=', $table . '.' . $secondKey)
           ->select($table . '.*')
           ->where($pivot . '.' . $firstKey, '=', $this->id);
   }

更新:使用

首先,您需要为incident_site

创建一个模型
class incident_site extends Model{
    public $table = 'incident_site';
    //your other code
}

Enviorment模型中添加Incidents()方法:

public function Incidents()
    {
        return $this->manyThroughMany('App\Incident', 'App\incident_site', 'site_id', 'id', 'incident_id');
}

更新

根据您的需要修改了功能 将您的功能更改为以下内容:

public function manyThroughMany($related, $through ,$middle , $firstKey, $secondKey, $pivotKey)
    {
        $model = new $related;
        $table = $model->getTable();
        $throughModel = new $through;
        $pivot = $throughModel->getTable();
        $middleModel = new $middle;
        $middleModelIds = $middleModel->where($this->getForeignKey(),$this->getKey())->get()->lists('id')->toArray();
        //$middleModelIds = $this->with($middleModel)->where()->get()->lists('id')->toArray();
        //$middleModelIds = $this->sites()->get()->lists('id')->toArray();
        return $model
            ->join($pivot, $pivot . '.' . $pivotKey, '=', $table . '.' . $secondKey)
            ->select($table . '.*')
            ->whereIn($pivot . '.' . $firstKey,$middleModelIds);// '=', $this->id);
    }

使用:
中间表的额外参数需要通过。

public function Incidents()
    {
        return $this->manyThroughMany('App\Incident', 'App\incident_site','App\Site','site_id', 'id', 'incident_id');
    }