1481 1066 1169 1591 1775 1929 1924 1293 1510 1687 1244 1268 1166 1375 1341 1293 1897 1922 1359 1141 1294 1366 1998 1899 1750 1739 1760 1167 1154 1834 1803 1239 1870 1079 1766 1375 1450 1399 1826 1497 1155 1824 1242 1068 1189 1227 1744 1197 1533 1990 1322 1887 1782 1241 1493 1717 1952 1033 1674 1734 1122 1189 1230 1613 1775 1342 1848 1116 1321 1117 1993 1261 1637 1533 1627 1488 1437 1814 1388 1043 1583 1948 1809 1601 1115 1898 1823 1331 1051 1006 1883 1177 1201 1610 1586 1631 1684 1993 1661 Database and Eloquent ORM: New features and improvements since the original Laravel 8 release (2/2) | PHPnews.io

PHPnews.io

Database and Eloquent ORM: New features and improvements since the original Laravel 8 release (2/2)

Written by Pascal Baljet Media - Blog / Original link on Nov. 13, 2021

This blog post follows up on last week's overview of the new Database and Eloquent features in Laravel 8 since the original release in September 2020. I already covered Collections, and next week is all about Jobs and Queues. Enjoy!

I got most code examples and explanations from the PRs and official documentation.

v8.41.0 Added Model::updateQuietly() (#37169)

Sometimes you may wish to "update" a given model without dispatching any events. You may accomplish this using the updateQuietly method, which uses the saveQuietly method under the hood:

$flight->updateQuietly(['departed' => false]);

As of v8.59, you may also use the createOneQuietly, createManyQuietly and createQuietly methods when using Model Factories:

Post::factory()->createOneQuietly();

Post::factory()->count(3)->createQuietly();

Post::factory()->createManyQuietly([
    ['message' => 'A new comment'],
    ['message' => 'Another new comment'],
]);

v8.41.0 Added Model key extraction to id on whereKey() and whereKeyNot() (#37184)

You can now use a Model instance with the whereKey and whereKeyNot methods:

$passenger->tickets()
    ->whereHas('airline', fn (Builder $query) => $query->whereKey($airline))
    ->get();

v8.42.0 Added withExists method to QueriesRelationships (#37302)

In addition to the withCount method, you may now use the withExists method to check the existence of a relationship:

// before:
$users = User::withCount('posts')->get();

$isAuthor = $user->posts_count > 0;

// after:
$users = User::withExists('posts')->get();

$isAuthor = $user->posts_exists;

// the column name can also be aliased:
$users = User::withExists([
    'posts as is_author',
    'posts as is_tech_author' => function ($query) {
        return $query->where('category', 'tech');
    },
    'comments',
])->get();

v8.42.0 Added loadExists on Model and Eloquent Collection (#37388)

This PR follows upon the withExists method in the example above. You may now use the loadExists method in both Model and Eloquent Collections:

$books = Book::all();

$books->loadExists(['author', 'publisher']);

v8.42.0 Added one-of-many relationship (inner join) (#37362)

One-to-one relations that are a partial relation of a one-to-many relation. You can retrieve the "latest" or "oldest" related model of the relationship:

/**
 * Get the user's most recent order.
 */
public function latestOrder()
{
    return $this->hasOne(Order::class)->latestOfMany();
}

/**
 * Get the user's oldest order.
 */
public function oldestOrder()
{
    return $this->hasOne(Order::class)->oldestOfMany();
}

/**
 * Get the user's largest order.
 */
public function largestOrder()
{
    return $this->hasOne(Order::class)->ofMany('price', 'max');
}

v8.43.0 Added eloquent strict loading mode (#37363)

You may instruct Laravel to always prevent the lazy loading of relationships. You should call this method within the boot method of your app's AppServiceProvider class.

Model::preventLazyLoading(! app()->isProduction());

v8.43.0 Added beforeQuery to base query builder (#37431)

This PR is a very advanced one! It allows you to change a "subselect"-builder, whereby the changes are also applied to the parent query builder. The preserved closures will be called before the query gets rendered. This way, you can keep "subquery"-builders alive and modify the subquery after applying it to the parent builder:

// 1. Add the subquery
$builder->beforeQuery(function ($query) use ($subQuery) {
    $query->joinSub($subQuery, ...);
});

// 2. Add constraints to the subquery
$subQuery->where('foo', 'bar');

// 3. Render the subquery, the constraints from 2. are applied
$builder->get();

v8.50.0 Added the possibility of having "Prunable" models (#37889)

You may want to periodically delete models that are no longer needed. With the Prunable trait Laravel will automatically remove obsolete model records from the database via a scheduled command.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;

class Flight extends Model
{
    use Prunable;

    /**
     * Get the prunable model query.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function prunable()
    {
        return static::where('created_at', '<=', now()->subMonth());
    }
}

The Artisan CLI command:

php artisan model:prune

You may also define a pruning method on the model, which will be called before the model is deleted:

protected function pruning()
{
    // Delete additional resources associated 
    // with the model, for example: files

    Storage::disk('s3')->delete($this->filename);
}

v8.53.0 Added immutable date and datetime casting (#38199)

Ssupport for accessing dates as immutable. Returns a CarbonImmutable instance instead of a Carbon instance.

class User extends Model
{
    public $casts = [
        'date_field'     => 'immutable_date',
        'datetime_field' => 'immutable_datetime',
    ];
}

v8.57.0 Added a simple where helper for querying relations (#38499)

You may now use the whereRelation and whereMorphRelation methods to query for a relationship's existence with a single, simple where condition attached to the relationship query:

// Before:
User::whereHas('posts', function ($query) {
    $query->where('published_at', '>', now());
})->get();

// After
User::whereRelation('posts', 'published_at', '>', now())->get();

// Morph relation
Comment::whereMorphRelation('commentable', '*', 'public', true);

v8.59.0 Added Eloquent builder whereMorphedTo method to streamline finding models morphed to another model (#38668)

The new whereMorphedTo and orWhereMorphedTo methods are a shortcut for adding a where condition looking for models that are morphed to a specific related model, without the overhead of a whereHas subquery:

Feedback::whereMorphedTo('subject', $user)->get();

Feedback::whereMorphedTo('subject', User::class)->get();

v8.59.0 Added support for disallowing class morphs (#38656)

You may call the enforceMorphMap method in the boot method of your apps' AppServiceProvider class. This disallows morphs without a morph map on it.

use Illuminate\Database\Eloquent\Relations\Relation;

Relation::enforceMorphMap([
    'post'  => Post::class,
    'video' => Video::class,
]);

v8.60.0 Added the valueOfFail() Eloquent builder method (#38707)

In addition to the value method, you may now use the valueOrFail method. This will throw a ModelNotFoundException if the model is not found.

// Before:
$votes = User::where('name', 'John')->firstOrFail('votes')->votes;

// Now:
$votes = User::where('name', 'John')->valueOrFail('votes');

v8.63.0 Added whereBelongsTo() Eloquent builder method (#38927)

The new whereBelongsTo method automatically determines the proper relationship and foreign key for the given model:

// Before:
$posts = Post::where('user_id', $user->id)->get();

// After:
$posts = Post::whereBelongsTo($user)->get();

pascalbaljetmedia

« New features and improvement in Laravel Jobs and Queues since the original v8.0 release - Database and Eloquent ORM: New features and improvements since the original Laravel 8 release (1/2) »