Apr 20, 2024 | Laravel 11 Laravel
Hello Dev,
In this tutorial, we'll explore how to implement the "Has Many Through" relationship in a Laravel 11 application using the `hasManyThrough()` method.
In Laravel, the "Has Many Through" relationship facilitates accessing distant relationships. Let's consider a scenario with three tables: "users," "posts," and "countries." Each user can have multiple posts, and each post is associated with a country. With the "Has Many Through" relationship, we can directly access posts belonging to a specific country. This simplifies querying and enables smooth traversal across multiple interconnected tables.
To establish this relationship, we'll utilize the `hasManyThrough()` method, enabling efficient navigation through related data.
Step 1: Generate MigrationsFirst, ensure you have the users and roles tables in your database. If not, you can create them using migrations. Additionally, you'll need a pivot table to manage the many-to-many relationship. By convention, Laravel uses the singular names of the two related tables, in alphabetical order, separated by an underscore.
php artisan make:migration create_users_table php artisan make:migration create_posts_table php artisan make:migration create_countries_tableRead Also: implementing many-to-many relationships in laravel 11 Step 2: Define the Schema for the Tables
In the create_users_table migration, define the schema for the "users" table, including a foreign key country_id that references the "countries" table.
users table migration:<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->foreignId('country_id')->constrained('countries'); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down(): void { Schema::dropIfExists('users'); } };
Similarly, define the schemas for the "posts" and "countries" tables, ensuring the "posts" table has a foreign key user_id that references the "users" table.
posts table migration:<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up(): void { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string("name"); $table->foreignId('user_id')->constrained('users'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down(): void { Schema::dropIfExists('posts'); } };countries table migration:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up(): void { Schema::create('countries', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down(): void { Schema::dropIfExists('countries'); } };Read Also: implementing one-to-many relationships in laravel 11 Step 3: Define the Has Many Through Relationship
In the Country model, define the posts method using the hasManyThrough method to establish the "Has Many Through" relationship.
User Model:<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasManyThrough; class Country extends Model { use HasFactory; /** * Write code on Method * * @return response() */ public function posts(): HasManyThrough { return $this->hasManyThrough( Post::class, User::class, 'country_id', /* Foreign key on users table... */ 'user_id', /* Foreign key on posts table... */ 'id', /* Local key on countries table... */ 'id' /* Local key on users table... */ ); } }Step 4: Accessing Related Models
With the relationship defined, you can now easily access posts for a specific country.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Country; class UserController extends Controller { /** * Write code on Method * * @return response() */ public function index(Request $request) { $country = Country::find(1); // Find a country by its ID $posts = $country->posts; // Access the posts for the country dd($posts); } }
This setup allows you to directly access posts from a country, simplifying queries and enabling seamless navigation through multiple related tables in your Laravel 11 application
Thank you for your encouragement! If you have any questions or need further assistance, feel free to ask. I'm here to help!
"Hey there! I'm a full-stack developer and proud owner of ItErrorSolution.com, based right here in India. I love nothing more than sharing handy tips and tricks with my fellow developers through easy-to-follow tutorials. When it comes to coding, I'm all about PHP, Laravel, Angular, Vue, Node, JavaScript, jQuery, CodeIgniter, and Bootstrap – been hooked on them forever! I'm all about putting in the work and staying committed. Ready to join me on this journey to coding?"