Laravel ‐ Chapter 18‐19 - pierre-akhrass/Lavarel-Docs GitHub Wiki
Chapter 18: Relationships in Laravel
Laravel Eloquent provides an expressive and convenient way to interact with your database using relationships. In this chapter, we cover:
- One-to-One Relationships
- One-to-Many Relationships
- Many-to-Many Relationships
- Polymorphic Relationships
One-to-One Relationships
A one-to-one relationship is used when a record in one table is associated with exactly one record in another table (e.g., a User
has one Profile
).
Example:
Profile Model:
class Profile extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
}
This indicates the profile
table contains the foreign key (user_id
).
Migration:
php artisan make:migration create_profiles_table
Inside the Migration:
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('avatar');
$table->string('address')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
// Alternative modern syntax:
// $table->foreignId('user_id')->constrained()->onDelete('cascade');
});
User Model:
class User extends Model
{
public function profile() {
return $this->hasOne(Profile::class);
}
}
Usage:
$user = User::find(1);
$profile = $user->profile;
$profile = Profile::find(1);
$user = $profile->user;
One-to-Many Relationships
In a one-to-many relationship, one record is associated with many records in another table. For example, a Category
has many Posts
.
Example:
Category Model:
class Category extends Model
{
public function posts() {
return $this->hasMany(Post::class);
}
}
Post Model:
class Post extends Model
{
public function category() {
return $this->belongsTo(Category::class);
}
}
Usage:
$category = Category::find(1);
$posts = $category->posts;
$post = Post::find(1);
$category = $post->category;
Many-to-Many Relationships
In a many-to-many relationship, multiple records in one table can be related to multiple records in another table (e.g., Posts
and Tags
).
Migration:
php artisan make:migration create_post_tag_table
php artisan make:model Tag
Migration file:
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('post_tag', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('post_id');
$table->unsignedBigInteger('tag_id');
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
Post Model:
class Post extends Model
{
public function tags() {
return $this->belongsToMany(Tag::class);
}
}
Tag Model:
class Tag extends Model
{
public function posts() {
return $this->belongsToMany(Post::class);
}
}
Usage:
$post = Post::find(1);
$tags = $post->tags;
$tag = Tag::find(1);
$posts = $tag->posts;
Managing Relationships:
$post->tags()->attach(1); // attach tag with id 1
$tag->posts()->detach(790); // remove relationship with post id 790
$tag->posts()->sync([79, 80]); // sync relationships
Why parentheses in method call?
$tag->posts
returns a Collection$tag->posts()
returns a Relationship instance for performing DB operations
Polymorphic Relationships
Polymorphic relationships allow a model to belong to more than one type of model on a single association (e.g., Images
attached to either Posts
or Users
).
Example: One-to-One Polymorphic
Database Structure:
images table:
- id
- url
- imageable_id
- imageable_type
Models:
Image Model:
class Image extends Model
{
public function imageable(): MorphTo {
return $this->morphTo();
}
}
Post/User Model:
public function image(): MorphOne {
return $this->morphOne(Image::class, 'imageable');
}
Example: Many-to-Many Polymorphic
Migration:
php artisan make:migration create_taggables_table
Schema::create('taggables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tag_id');
$table->unsignedBigInteger('taggable_id');
$table->string('taggable_type');
$table->timestamps();
});
Models:
Tag Model:
public function posts() {
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos() {
return $this->morphedByMany(Video::class, 'taggable');
}
Post Model:
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
Summary of Methods:
morphOne()
– one-to-one polymorphicmorphMany()
– one-to-many polymorphicmorphToMany()
– many-to-many polymorphicmorphedByMany()
– inverse many-to-many polymorphic
Conclusion
Laravel’s Eloquent ORM provides robust support for relationships, making it easy to:
- Retrieve related data
- Perform DB operations through model methods
- Avoid writing complex SQL joins
- Reuse structures like tags or images across multiple models using polymorphism
Chapter 19: General Features
This chapter explores a variety of important features in Laravel that are commonly used across different types of web applications. It covers configuration, logging, pagination, mail handling, helper functions, collections, loading strategies (lazy vs eager), mutators/accessors, localization, queues, error handling, and more.
Environment Variables & Custom Configuration
Laravel uses a .env
file to store environment variables that help configure the application per environment (development, production, etc.).
Custom Config Files
You can create your own configuration files in the config/
directory:
- Create a PHP file (e.g.
myconfig.php
) - Return an array with your configuration keys:
return [ 'example' => 'value' ];
- Access it using
config('myconfig.example')
Logging
Laravel provides extensive logging options via the config/logging.php
file.
Channels
- Stack: Default; logs to multiple channels.
- Single: Logs to a single file.
- Daily: Rotates logs daily.
Configuration
'channels' => [
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
],
Log Levels
From lowest to highest priority:
debug
, info
, notice
, warning
, error
, critical
, alert
, emergency
Log Formatters
You can customize how logs are formatted using a formatter
.
Custom Pagination
Laravel provides two main pagination types:
- Paginator – used for simple next/prev navigation.
- LengthAwarePaginator – provides total pages info.
Usage:
Post::paginate(10); // LengthAwarePaginator
Post::simplePaginate(10); // Paginator
Mail System
Laravel uses the Mailable
class to send emails.
Steps:
-
Create a mailable:
php artisan make:mail WelcomeUser
-
Define the email logic in the class:
public function build() { return $this->view('emails.welcome'); }
-
Send it:
Mail::to('[email protected]')->send(new WelcomeUser());
Features:
- Support for cc, bcc, and mass mailing
- Parameterized templates
- Markdown mail components
Helper Functions
Laravel allows creating global helper functions.
Steps:
- Create a file like
app/helpers.php
- Add functions:
function greet($name) { return "Hello, $name!"; }
- Add to
composer.json
:"autoload": { "files": ["app/helpers.php"] }
- Run
composer dump-autoload
Collections
Collections are Laravel’s wrapper over PHP arrays and include many useful methods like:
map()
filter()
pluck()
groupBy()
Example:
collect([1, 2, 3])->map(fn($v) => $v * 2);
Lazy vs Eager Loading
Lazy Loading (Default)
$posts = Post::all(); // multiple queries
Eager Loading (Recommended for performance)
$posts = Post::with('comments')->get(); // single optimized query
Mutators and Accessors
Mutators and accessors allow automatic data transformation when saving or retrieving model attributes.
Mutator:
public function setNameAttribute($value) {
$this->attributes['name'] = strtolower($value);
}
Accessor:
public function getNameAttribute($value) {
return ucfirst($value);
}
Localization & Translations
Laravel supports multilingual applications using translation strings and language files in resources/lang
.
Steps:
-
Publish language files:
php artisan lang:publish
-
Add translations:
__('messages.welcome') // e.g., returns “Welcome” in the user’s language
-
Middleware can prefix routes with language codes (e.g.
/en/posts
,/fr/posts
).
Custom @vite Attributes
You can modify how Laravel includes assets with Vite, including custom attributes or tags.
Remove /public or /index.php from URLs
To avoid /public
in your URLs:
- Set your web server's root to
public/
- Use
.htaccess
or Nginx rewrite rules
Queues & Jobs
Jobs allow background processing (e.g., emails, image processing).
Example:
-
Create a Job:
php artisan make:job SendEmailJob
-
Dispatch the job:
dispatch(new SendEmailJob($user));
-
Configure queue driver in
.env
(e.g. database, redis)
Other Useful Features
Failed Jobs
Laravel records failed jobs and allows retrying them.
Custom Exceptions
You can create custom exception classes and handle them in the Handler.php
file.
Throttling
Control API request limits via middleware:
Route::middleware('throttle:60,1')->group(...);
Conclusion
This chapter introduces general Laravel features that go beyond basic CRUD. It equips you to:
- Manage config, logs, and mail
- Optimize performance with eager loading
- Improve code with accessors/mutators
- Handle multilingual sites
- Build scalable systems using queues
- Customize your project structure and helper functions