Mar*_*łek 2 laravel eloquent laravel-5
我想在我的应用程序中有许多模型/模块,但有些客户端会删除它们中的一些.
现在我有这样的关系:
public function people()
{
return $this->hasMany('People', 'model_id');
}
Run Code Online (Sandbox Code Playgroud)
当我运行$model = Model::with('people')->get();它工作正常
但如果People模型不存在怎么办?
目前我得到了:
ClassLoader.php第386行中的1/1 ErrorException:include(...):无法打开流:没有这样的文件或目录
我试过了
public function people()
{
try {
return $this->hasMany('People', 'model_id');
}
catch (FatalErrorException $e) {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
或者:
public function people()
{
return null; // here I could add checking if there is a Model class and if not return null
}
Run Code Online (Sandbox Code Playgroud)
但是使用这种方法时$model = Model::with('people')->get();不起作用.
我将有几十个关系,我不能列出它们用于with.最好的方法是使用一些empty relation(返回null)只是为了使Eloquent不做任何事情,但在这种情况下,Eloquent仍然试图让它工作,我会得到:
哎呀,看起来像出事了.Builder.php第430行中的1/1 FatalErrorException:在null上调用成员函数addEagerConstraints()
那有什么简单的解决方案吗?
我能提出的唯一解决方案是创建自己的Eloquent\Builder类.
我打电话给它MyBuilder.让我们首先确保它实际使用.在您的模型中(最好是基本模型)添加此newEloquentBuilder方法:
public function newEloquentBuilder($query)
{
return new MyBuilder($query);
}
Run Code Online (Sandbox Code Playgroud)
在自定义Builder类中,我们将覆盖该loadRelation方法并在关系上调用if null之前添加一个检查addEagerConstraints(或者在您的情况下null)
class MyBuilder extends \Illuminate\Database\Eloquent\Builder {
protected function loadRelation(array $models, $name, Closure $constraints)
{
$relation = $this->getRelation($name);
if($relation == null){
return $models;
}
$relation->addEagerConstraints($models);
call_user_func($constraints, $relation);
$models = $relation->initRelation($models, $name);
$results = $relation->getEager();
return $relation->match($models, $results, $name);
}
}
Run Code Online (Sandbox Code Playgroud)
该函数的其余部分基本上与原始构建器(Illuminate\Database\Eloquent\Builder)中的代码完全相同
现在只需在关系函数中添加这样的东西,它应该全部工作:
public function people()
{
if(!class_exist('People')){
return null;
}
return $this->hasMany('People', 'model_id');
}
Run Code Online (Sandbox Code Playgroud)
如果你想像关系一样使用它,它会变得有点棘手.
您必须覆盖该getRelationshipFromMethod功能Eloquent\Model.所以让我们创建一个基础模型(你的模型显然需要扩展它......)
class BaseModel extends \Illuminate\Database\Eloquent\Model {
protected function getRelationshipFromMethod($key, $camelKey)
{
$relations = $this->$camelKey();
if ( $relations instanceof \Illuminate\Database\Eloquent\Collection){
// "fake" relationship
return $this->relations[$key] = $relations;
}
if ( ! $relations instanceof Relation)
{
throw new LogicException('Relationship method must return an object of type '
. 'Illuminate\Database\Eloquent\Relations\Relation');
}
return $this->relations[$key] = $relations->getResults();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要修改关系以返回空集合
public function people()
{
if(!class_exist('People')){
return new \Illuminate\Database\Eloquent\Collection();
}
return $this->hasMany('People', 'model_id');
}
Run Code Online (Sandbox Code Playgroud)
并更改loadRelation函数MyBuilder以检查类型集合而不是null
protected function loadRelation(array $models, $name, Closure $constraints)
{
$relation = $this->getRelation($name);
if($relation instanceof \Illuminate\Database\Eloquent\Collection){
return $models;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2886 次 |
| 最近记录: |