提问者:小点点

Laravel 5.2雄辩-多对多关系模型


我有3个模型:环境、站点和事件。每个都有各自的表格。

我的模型关系定义如下:

环境有许多站点(environment\u id在站点表中)

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

站点属于一个环境(Environment\u id在站点表中),并且属于许多事件(具有incident\u idsite\u id的事件站点关系表)

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

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

事件属于多个站点(带有事件id站点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();
    }]);

但在应用程序的其他领域使用它并不理想。

问:我如何通过环境模型中的方法来实现上述关系?有没有更简单的方法?


共1个答案

匿名用户

没有在多对多关系中使用hasManyBy()的任何规定。但是你可以通过使用DB::ra()来实现这一点,或者你可以像这个论坛中给出的那样在你的BaseModel中添加以下函数。

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\u站点创建一个模型

class incident_site extends Model{
    public $table = 'incident_site';
    //your other code
}

在您的环境模型中添加事件()方法:

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');
    }