Laravel Defining Eloquent Models


In Laravel, an Eloquent model represents a table in your database, and each instance of a model corresponds to a single row in that table. Eloquent models allow you to interact with your database using an object-oriented approach instead of writing raw SQL queries.

Steps to Define an Eloquent Model:


1. Creating an Eloquent Model

You can create an Eloquent model using the Artisan command-line tool. For example, to create a Post model, you would run:

php artisan make:model Post

This will create a model class in the app/Models directory (or in app/ if you're using an older version of Laravel). By default, Laravel assumes the table name for the model will be the plural form of the model's class name (i.e., posts for the Post model).


2. Structure of an Eloquent Model

A typical Eloquent model looks like this:

namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { // Model logic and methods go here }

Key elements:

  • Namespace: The model is typically stored in the App\Models namespace.
  • Inheritance: The model extends Illuminate\Database\Eloquent\Model, making it an Eloquent model.
  • Attributes: You can define attributes like $table, $fillable, $guarded, and timestamps that affect how the model behaves.

3. Mapping Models to Tables

By default, Eloquent assumes the table name is the plural form of the model name (Post -> posts). You can override this if needed by defining the $table property.

class Post extends Model { protected $table = 'my_posts'; }

4. Primary Key

Eloquent also assumes that each table has a primary key named id. If your primary key has a different name, you can specify it with the $primaryKey property:

class Post extends Model { protected $primaryKey = 'post_id'; }

5. Timestamps

By default, Eloquent expects created_at and updated_at columns in your database table to automatically manage timestamps. If you don't want to use these columns, you can disable timestamps by setting the $timestamps property to false:

class Post extends Model { public $timestamps = false; }

You can also customize the names of these timestamp columns if necessary:

class Post extends Model { const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update'; }

6. Mass Assignment: $fillable vs $guarded

When creating or updating models, you can pass an array of attributes to the model. To protect certain fields from being mass-assigned (i.e., accidentally inserted into the database), you must define which fields can be filled using $fillable or which fields should not be assigned using $guarded.

$fillable

The $fillable property is an array that defines which attributes should be mass-assignable:

class Post extends Model { protected $fillable = ['title', 'content']; }

Now, you can safely assign the title and content fields:

Post::create(['title' => 'My Title', 'content' => 'My Content']);

$guarded

Alternatively, $guarded is an array of attributes that you don’t want to be mass-assigned. All other attributes will be mass-assignable.

class Post extends Model { protected $guarded = ['id']; }

This means that the id field is protected from mass assignment, but all other fields can be mass-assigned.


7. Model Methods

You can define methods within your models for logic related to that model.

Example:

class Post extends Model { public function publish() { $this->published = true; $this->save(); } }

Now you can call this method on any Post instance:

$post = Post::find(1); $post->publish();

8. Accessors and Mutators

Eloquent models allow you to define accessors (for retrieving values) and mutators (for modifying values before saving them to the database). This helps format your data before it is saved or after it is retrieved.

Accessor Example (modifying data when retrieved):

class Post extends Model { public function getTitleAttribute($value) { return strtoupper($value); } }

Now every time you access the title attribute, it will be uppercase.

Mutator Example (modifying data before saving):

class Post extends Model { public function setTitleAttribute($value) { $this->attributes['title'] = strtolower($value); } }

This will automatically convert the title to lowercase before saving it to the database.


9. Query Scopes

Eloquent allows you to define reusable query logic using local scopes and global scopes.

Local Scopes (for common queries):

Define a scope in the model by adding a scope prefix to the method name:

class Post extends Model { public function scopePublished($query) { return $query->where('status', 'published'); } }

You can now use this scope in your queries:

$posts = Post::published()->get();

Global Scopes (apply to every query on the model):

To define a global scope, you would typically create a custom class that implements the Scope interface. Then, you apply it to your model.


10. Relationships

Eloquent makes it easy to define relationships between different models. Common relationships include:

  • One-to-One (hasOne)
  • One-to-Many (hasMany)
  • Many-to-Many (belongsToMany)
  • Polymorphic relationships (for models that belong to multiple other models)

Example: One-to-Many Relationship

class Post extends Model { public function comments() { return $this->hasMany(Comment::class); } }

You can then access the comments for a given post like this:

$post = Post::find(1); $comments = $post->comments;

Summary

Defining an Eloquent model in Laravel involves:

  1. Creating the model class.
  2. Associating it with a database table (using conventions or explicit configuration).
  3. Defining properties and methods to work with the table’s data.
  4. Using mass assignment protection, relationships, query scopes, and other features to interact with the data easily.

Eloquent models make database interaction in Laravel cleaner, faster, and more maintainable by leveraging object-oriented principles.