Suppose there are three tables - authors, books and rating. In this post, we will see some example codes of using relationships and some filtering records also from these tables.
Step 01: create fresh laravel project
composer create-project laravel/laravel query_records_with_relationship
Step 02: Setting Up scaffolding migration of Author with artisan command
php artisan make:model Author -m
Step 03: Setting Up scaffolding migration of Book with artisan command
php artisan make:model Book -m
Step 04: Setting Up scaffolding migration of Rating with artisan command
php artisan make:model Rating -m
Step 05: Specifying migration definition authors
public function up() { Schema::create('authors', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); }
Step 06: Specifying migration definition for books
public function up() { Schema::create('books', function (Blueprint $table) { $table->id(); $table->foreignId('author_id')->constrained(); $table->string('title'); $table->timestamps(); }); }
Step 07: Specifying migration definition for ratings
public function up() { Schema::create('ratings', function (Blueprint $table) { $table->id(); $table->foreignId('book_id')->constrained(); $table->integer('rating'); $table->timestamps(); }); }
Step 08: Setting up relationship in Author model in App\Models\Author.php
public function books() { return $this->hasMany(Book::class); }
Step 09: Setting up relationship in Book model in App\Models\Book.php
public function author() { return $this->belongsTo(Author::class); } public function ratings() { return $this->hasMany(Rating::class); }
Step 10: Seeding Author, Book and Rating in DatabaseSeeder.php
// at the top use Faker\Generator; public function run() { $faker = app(Generator::class); for( $i=0; $i < 10 ; $i++ ) { \App\Models\Author::create([ 'title' => $faker->text(50), ]); } $authorIds = \App\Models\Author::pluck('id'); for( $i=0; $i < 100 ; $i++ ) { \App\Models\Book::create([ 'author_id' => $authorIds->random(), 'title' => $faker->text(50), ]); } $bookIds = \App\Models\Book::pluck('id'); for( $i=0; $i < 100 ; $i++ ) { \App\Models\Rating::create([ 'book_id' => $bookIds->random(), 'rating' => rand(1,5) ]); } }
Step 11: Create BookController using artisan command
php artisan make:controller BookController
Step 12: Now creating list of methods ( six ) inside BookController.php to illustrate examples of using relationship to query records
Defining routes in web.php
Route::get('/', [BookController::class, 'filterWithRelationship']); Route::get('/hasOneBook', [BookController::class, 'hasOneBook']); Route::get('/hasNotAnyBook', [BookController::class, 'hasNotAnyBook']); Route::get('/hasMoreThanFiveBooks', [BookController::class, 'hasMoreThanFiveBooks']); Route::get('/getAuthorWithRatedBooks', [BookController::class, 'getAuthorWithRatedBooks']); Route::get('/getAuthorWithBookTitle', [BookController::class, 'getAuthorWithBookTitle']);
Back in BookController.php adding following six methods
function filterWithRelationship() { // querying books by certain author by his name but only with some title containing something in it $author = Author::where('name', 'Franco Ebert')->first(); $books = $author->books()->where('title', 'like', '%lu%')->pluck('title')->dd(); } function hasOneBook() { // querying authors who have at least 1 book in database Author::has('books')->get()->dd(); } function hasNotAnyBook() { // querying author does not have any book Author::doesntHave('books')->get()->dd(); } function hasMoreThanFiveBooks() { // querying authors who have more than five books Author::has('books', '>', 5)->get()->dd(); } function getAuthorWithRatedBooks() { // querying authors that have rated books ( at least 1 rating ) Author::has('books.ratings')->get()->dd(); } // filtering child records/ relation with where statement to get parent records function getAuthorWithBookTitle() { // querying authors based on given book title on books records Author::wherehas( 'books', function ( $query ){ $query->where('title', 'like', '%ab%'); })->get()->dd(); }