问题
I have 3 Models.
- Project {id, name}
- Platform {id, name}
- Version {id, value}
One Project can have multiple Platforms and each Platform can have multiple Versions within a Project. I have the following table which relates the models:
As you can see Project 6 has versions 1 and 3 on platform 1, while Project 8 has versions 1 and 2 on the same platform.
I want to get all Projects' Platforms and versions of those Platforms depending on the Project.
For example, I'd like to do
App\Project::find(6)->platform()->with('version')->get();
and get only versions with ids of 1 and 3 on my version collection of platform 1 of this project.
This is what I have in Project Model:
public function platform()
{
return $this->belongsToMany('App\Platform')->withPivot('version_id')->distinct();
}
This is what I have in Platform Model:
public function version()
{
return $this->belongsToMany('App\Version', 'platform_project')->distinct();
}
Could you please help me figure out the best way to achieve the desired result?
回答1:
In this case you should use the hasManyThrough relationship.
Definition:
The "has-many-through" relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. For example, a Country model might have many Post models through an intermediate User model. In this example, you could easily gather all blog posts for a given country.
Try this:
Project Model
public function versions()
{
return $this->hasManyThrough(
'App\Version',
'App\Platform',
);
}
The first argument passed to the hasManyThrough method is the name of the final model we wish to access, while the second argument is the name of the intermediate model.
Typical Eloquent foreign key conventions will be used when performing the relationship's queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the hasManyThrough method. The third argument is the name of the foreign key on the intermediate model. The fourth argument is the name of the foreign key on the final model. The fifth argument is the local key, while the sixth argument is the local key of the intermediate model:
So you can acess all project version's like this:
$projectVersions = Project::find($id)->versions();
foreach($projectVersions as $version)
{
echo $version->value; // this will echo each version value from the given project
}
Also, i think you should change your relationships to hasMany
Project Model
public function platforms()
{
return $this->hasMany('App\Platform')->distinct();
}
Platform Model
public function versions()
{
return $this->hasMany('App\Version')->distinct();
}
public function project()
{
return $this->belongsTo('App\Project');
}
Version Model
public function platform()
{
return $this->belongsTo('App\Platform');
}
回答2:
try this:
App\Project::find(6)->with(['platform' => function($q){
$q->with(['version']);
}])->get();
i hope help you
来源:https://stackoverflow.com/questions/54987671/3-models-relationship-in-laravel-5