Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
291 views
in Technique[技术] by (71.8m points)

laravel - use indirect relation when intermediate model is empty

i have made indirect relation from one model to another in couple of my models.

this is my Work Model:

public function GeoEntities()
{
    return $this->hasMany(AppGeoEntity::class);
}

public function geoLand()
{
    $builder = $this->GeoEntities()->where("entity_type", 0);
    $relation = new HasOne($builder->getQuery(), $this, 'work_id', 'id');
    return $relation;
}

public function geoLandPoints()
{
    return $this->geoLand->geoPoints();
}

this return $this->intermediateModel->FinalModel(); would work, if intermediate relation is belongsTo() and returns a relation instance.

but in this case, when geoLand is Empty it produce error:

Call to a member function geoPoints() on null

like below line:

$points = $work->geoLandPoints;
  • The Intermediate Relation is a hasMany

i want to have this like relation call geoLandPoints and not geoLandPoints() but,

when intermidate models are null, i want an empty relation.

but i can not figure it out, how to achieve this.

with Fico7489LaravelEloquentJoinTraitsEloquentJoin

using Fico7489LaravelEloquentJoinTraitsEloquentJoin package, i have tried to refactor relation like below:

public function geoLandPoints()
{
    $builder = $this
        ->select("works.*")
        ->join("geo_entities", "works.id", "geo_entities.work_id")
        ->join("geo_points", "geo_entities.id", "geo_points.geo_entity_id")
        ->where("entity_type", 0)
        ->where("works.id", $this->id);
    return new HasMany($builder->getQuery(), $this, "work_id", "id");
}

but it couldn't convert Database Query Builder to Eloquent Query Builder.

Argument 1 passed to IlluminateDatabaseEloquentRelationsHasOneOrMany::__construct() must be an instance of IlluminateDatabaseEloquentBuilder, instance of IlluminateDatabaseQueryBuilder given

question from:https://stackoverflow.com/questions/66050813/use-indirect-relation-when-intermediate-model-is-empty

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why don't you use the hasOne() method instead of trying to return your own HasOne class? Also, you can use withDefault() so the relationship returns an empty GeoEntity instead of null.

public function geoLand()
{
    return $this->hasOne(AppGeoEntity::class)->where("entity_type", 0)->withDefault();
}

You could even pass an array of default values. withDefault(['column' => 'value', 'column2' => 'value2', ...])


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...