PHP
Implementing a Has Many Through Relationship
Learn how to define a "has many through" relationship in Laravel Eloquent to conveniently access a distant relationship by traversing an intermediate model in your application.
// Scenario: A Country has many Users, and each User has many Posts.
// We want to get all Posts for a given Country directly.
// 1. Define the Country model (app/Models/Country.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Country extends Model
{
use HasFactory;
public function users()
{
return $this->hasMany(User::class);
}
// Define the "has many through" relationship to Posts
public function posts()
{
return $this->hasManyThrough(Post::class, User::class);
}
}
// 2. Define the User model (app/Models/User.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class User extends Model
{
use HasFactory;
public function country()
{
return $this->belongsTo(Country::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
}
// 3. Define the Post model (app/Models/Post.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model
{
use HasFactory;
public function user()
{
return $this->belongsTo(User::class);
}
}
// Usage: Get all posts from a specific country
$country = App\Models\Country::find(1);
$countryPosts = $country->posts; // Collection of Post models
How it works: The `hasManyThrough` relationship provides a convenient shortcut for accessing distant relationships through an intermediate model. In the example, a `Country` model can directly access its `Post` models (which belong to `User` models) through the `User` model. The `hasManyThrough` method takes the final model name (`Post::class`) as the first argument and the intermediate model name (`User::class`) as the second. This simplifies querying and avoids needing to manually chain multiple relationships.