我有3个模型:环境、站点和事件。每个都有各自的表格。
我的模型关系定义如下:
环境有许多站点(environment\u id
在站点表中)
public function sites()
{
return $this->hasMany('App\Site');
}
站点属于一个环境(Environment\u id
在站点表中),并且属于许多事件(具有incident\u id
和site\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();
}]);
但在应用程序的其他领域使用它并不理想。
问:我如何通过环境模型中的方法来实现上述关系?有没有更简单的方法?
没有在多对多关系中使用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');
}