Dorokhov.codes

ORM: Eloquent

Create a model:

# Laravel will be looking for `posts` table in the DB:
php artisan make:model Post
# Create a model with migration:
php artisan make:model Post -m

Example: app/Post.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model {
    // ...
}

If we have another table:

protected $table = 'posts';

If we don’t use standard id key:

protected $primaryKey = 'code';
// if we don't use autoincrement:
public $incrementing = false;
// Type of the primary key if it's not integer:
protected $keyType = 'string';

Disable filling timestamps:

public $timestamps = false;

Values for columns by default:

protected $attributes = [
    'title' => 'Hello',
    'description' => 'Empty',
];

Creating a new record

$post = new Post();
$post->title = 'Hello';
$post->description = 'Test';
$post->save();
$post = Post::create([
    'title' => 'test',
    'description' => 'test',
]);
$post = new Post();
$post->fill([
    'title' => 'test',
    'description' => 'test',
]);
$post->save();

We should specify fillable columns to use the create() method:

protected $fillable = [
    'title',
    'description',
];

Create from a form:

Post::create($request->all());

Getting records

All records:

$posts = Post::all();

Using query builder:

$posts = Post::limit(5)->get();
// Or:
$posts = Post::query()->limit(5)->get();
// Order:
$posts = Post::orderBy('created_at', 'desc')->get();
$posts = Post::limit(5)->where('category', 4)->get();
$post = Post::find(2);

If we need only certain fields:

$posts = Post::all()->pluck('title');
$posts = Post::all()->pluck('title', 'id'); // We will get an array id => title.

Updating

$post = Post::find(2);
$post->title = "hello";
$post->save();

Bulk updating:

Post::where('id', '>', 3)->update(['title' => 'hello']);

Deleting

$post = Post::find(2); // Can be null
$post->delete();
Post::destroy(8); // If a records doesn't exist, nothing will happen
Post::destroy([3, 4, 6]);

Relationships

One to one

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
 
class User extends Model
{
    /**
     * Get the phone associated with the user.
     */
    public function phone(): HasOne
    {
        return $this->hasOne(Phone::class);
    }
}

Eloquent determines the foreign key of the relationship based on the parent model name. In this case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method:

return $this->hasOne(Phone::class, 'foreign_key');

Using:

$phone = User::find(1)->phone;

Defining the inverse of the relationship:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class Phone extends Model
{
    /**
     * Get the user that owns the phone.
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

If a foreign key is different:

return $this->belongsTo(User::class, 'foreign_key');
return $this->belongsTo(User::class, 'foreign_key', 'owner_key');

One to many

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
 
class Post extends Model
{
    /**
     * Get the comments for the blog post.
     */
    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }
}

Inverse:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }
}

Modifying requests:

$comment = Post::find(1)->comments()
                    ->where('title', 'foo')
                    ->first();

Eager loading (using with() method):

$users = User::with('podcasts')->get();
 
foreach ($users->flatMap->podcasts as $podcast) {
    echo $podcast->subscription->created_at;
}

Many to many

We should create one additional table:

users
    id - integer
    name - string
 
roles
    id - integer
    name - string
 
role_user
    user_id - integer
    role_id - integer

And then the same:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class User extends Model
{
    /**
     * The roles that belong to the user.
     */
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class);
    }
}

Inverse:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class Role extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class);
    }
}