In Laravel, models play a central role in the architecture of any application. They act as the connection between your PHP code and your database. While controllers handle incoming requests and views display content to the user, models handle data retrieval, manipulation, and storage. Understanding models is essential for building dynamic applications that interact with databases efficiently.
Laravel uses the Eloquent ORM, which makes model creation and database interaction extremely expressive and intuitive. This complete guide explores creating models, understanding their structure, conventions, relationships, attributes, query methods, best practices, and advanced features. We will also dive deeply into the Artisan command used to generate models, how models map to database tables, how to customize configurations, and how to use additional flags during model creation.
This article walks you through everything you need to know about creating and working with models in Laravel.
What Is a Model in Laravel
A model in Laravel is a PHP class that represents a specific database table. It allows developers to interact with the table through a simple and expressive syntax rather than writing raw SQL queries. With Laravel models, you can perform operations such as retrieving data, inserting records, updating rows, and deleting entries in a clean and object oriented way.
Models live inside the app/Models/ directory, and each model corresponds to a table in the database by following Laravel’s naming conventions. For example, a Product model corresponds to a products table. The model handles the logic of interacting with this table.
Understanding Eloquent ORM and Its Role
Eloquent ORM stands for Object Relational Mapping. It allows you to work with database tables as if they were simple PHP objects. Instead of writing SQL, you can call methods on the model to perform actions.
Eloquent provides:
- Easy querying using method chains
- Automatic handling of relationships
- Clean and readable syntax
- Mass assignment features
- Attribute casting and mutators
- Timestamps management
Because of these features, Laravel models become the foundation of most applications.
Using Artisan to Create a Model
Laravel provides the Artisan command line tool, which speeds up development. The simplest way to create a model is by using this command:
php artisan make:model Product
This command generates a new model file at:
app/Models/Product.php
The file contains a basic class skeleton. Laravel automatically assumes that the model corresponds to the products table, thanks to its naming convention.
Understanding Laravel Naming Conventions
Laravel follows specific naming conventions to reduce configuration:
- Model name is singular:
Product - Database table name is plural:
products
This means you do not need to manually specify the table name unless you want to override the convention.
If you do need to define a custom name, you can do so inside the model:
protected $table = 'my_products';
But normally, the default conventions are enough.
Structure of a Newly Generated Model File
When you generate a model, Laravel gives you a minimal file:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
//
}
This class extends Model, which gives it all Eloquent ORM features. Although it looks empty, the model has everything required to interact with the corresponding database table.
Adding Fillable Attributes
To allow mass assignment, you must define which attributes can be assigned in bulk:
protected $fillable = [
'name',
'price',
'description'
];
Mass assignment allows you to create new records like this:
Product::create([
'name' => 'Keyboard',
'price' => 99,
'description' => 'Mechanical keyboard'
]);
Guarded Attributes
Alternatively, you can protect fields by defining guarded attributes:
protected $guarded = ['id'];
This means all fields except id can be mass assigned.
Creating a Model with a Migration
Often, you want a model and its database table created together. Laravel allows this with a flag:
php artisan make:model Product -m
This generates both:
- Model file
- Migration file
The migration file lets you define the structure of the products table.
Creating a Model with All Supporting Files
Laravel can generate additional files with one command:
php artisan make:model Product -a
This creates:
- Model
- Migration
- Factory
- Seeder
- Controller
This is useful for full CRUD setups.
Creating a Model with a Controller
If you want a model and controller at the same time:
php artisan make:model Product -c
To generate a resource controller:
php artisan make:model Product -cr
Creating a Model with a Factory
Factories help create dummy data:
php artisan make:model Product -f
Creating a Model with a Seeder
To generate a seeder with the model:
php artisan make:model Product -s
Creating a Model with a Policy
Policies manage authorization:
php artisan make:model Product -p
How Eloquent Determines the Table Name
By default, Eloquent pluralizes the model name. For example:
- Model:
User→ Table:users - Model:
Category→ Table:categories - Model:
Product→ Table:products
If needed, override it:
protected $table = 'store_products';
How Eloquent Determines the Primary Key
By default, the primary key is:
protected $primaryKey = 'id';
And it expects an incrementing integer. To customize:
public $incrementing = false;
protected $primaryKey = 'product_code';
protected $keyType = 'string';
Using Timestamps in Models
Laravel expects created_at and updated_at columns. If your table does not use timestamps:
public $timestamps = false;
Connecting Models to the Database
Laravel reads database configurations from:
config/database.php
And loads data from the .env file. You do not need to configure models manually unless working with multiple connections.
Querying the Database Using the Model
Models allow elegant query construction.
Getting All Records
Product::all();
Getting One Record
Product::find(1);
Using Where Clauses
Product::where('price', '>', 50)->get();
Ordering Results
Product::orderBy('price', 'asc')->get();
Paginating Results
Product::paginate(15);
Inserting New Records
You can insert using mass assignment:
Product::create([
'name' => 'Laptop',
'price' => 1200
]);
Or manually:
$product = new Product;
$product->name = 'Phone';
$product->price = 500;
$product->save();
Updating Records
$product = Product::find(1);
$product->price = 150;
$product->save();
Deleting Records
Product::find(1)->delete();
Or mass delete:
Product::where('price','<',10)->delete();
Model Relationships in Laravel
Models can define relationships between tables.
One to One Relationship
public function user()
{
return $this->hasOne(User::class);
}
One to Many Relationship
public function reviews()
{
return $this->hasMany(Review::class);
}
Many to Many Relationship
public function categories()
{
return $this->belongsToMany(Category::class);
}
Belongs To Relationship
public function brand()
{
return $this->belongsTo(Brand::class);
}
Attribute Casting
Casting converts attributes automatically:
protected $casts = [
'is_active' => 'boolean',
'price' => 'integer',
];
Model Observers
Observers allow listening to model events:
- created
- updated
- deleted
- restored
- saving
- saved
Model Factories and Seeding
Factories allow easy generation of fake data:
Product::factory()->count(50)->create();
Seeders let you populate the database:
php artisan db:seed --class=ProductSeeder
Soft Deleting Models
Soft delete moves a record to the trash instead of deleting permanently.
Enable it:
use Illuminate\Database\Eloquent\SoftDeletes;
Add to model:
class Product extends Model
{
use SoftDeletes;
}
Migration must include:
$table->softDeletes();
Accessors and Mutators
Accessors transform values when retrieved:
public function getNameAttribute($value)
{
return ucfirst($value);
}
Mutators transform values when stored:
public function setNameAttribute($value)
{
$this->attributes['name'] = strtolower($value);
}
Model Scopes
Scopes allow reusable query logic.
Local Scope
public function scopeActive($query)
{
return $query->where('is_active', 1);
}
Use it:
Product::active()->get();
Global Scope
Apply a condition to all queries:
protected static function booted()
{
static::addGlobalScope('active', function ($query) {
$query->where('is_active', 1);
});
}
Model Events
You can listen for events inside the model:
protected static function boot()
{
parent::boot();
static::created(function ($product) {
//
});
}
Mass Assignment Protection
Laravel protects you from mass assignment attacks. Always define:
$fillable
Or use:
$guarded
Model Best Practices
- Always define
$fillableor$guarded - Use descriptive model names
- Keep model logic minimal
- Use scopes for reusable conditions
- Use relationships instead of join queries
- Use factories for testing
- Keep database logic out of controllers
Example of a Complete Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'price',
'description',
'is_active'
];
public function brand()
{
return $this->belongsTo(Brand::class);
}
public function scopeActive($query)
{
return $query->where('is_active', 1);
}
}
Leave a Reply