Під час роботи з колекціями Eloquent вам може знадобитися додати специфічну функціональність, що стосується певних типів моделей. Новий атрибут CollectedBy у Laravel надає декларативний спосіб налаштування колекцій без необхідності переопределяти методи моделі, що робить ваш код більш зрозумілим і легким для підтримки.
Раніше для персоналізації колекцій моделей потрібно було переоприділяти метод newCollection(), але теперній підхід на основі атрибутів пропонує більш акуратне рішення на рівні класу.
use Illuminate\Database\Eloquent\Attributes\CollectedBy;
#[CollectedBy(CustomCollection::class)]
class YourModel extends Model
{
// Реалізація моделі
}
Розглянемо практичний приклад з каталогу продуктів електронної комерції:
// Колекція продуктів
<?php
namespace App\Collections;
use Illuminate\Database\Eloquent\Collection;
class ProductCollection extends Collection
{
public function inStock()
{
return $this->filter(fn($product) => $product->stock_count > 0);
}
public function onSale()
{
return $this->filter(fn($product) => $product->discount_percentage > 0);
}
public function byPriceRange($min, $max)
{
return $this->filter(function($product) use ($min, $max) {
$price = $product->getEffectivePrice();
return $price >= $min && $price <= $max;
});
}
public function topRated()
{
return $this->filter(fn($product) => $product->average_rating >= 4)
->sortByDesc('average_rating');
}
}
// Модель продукту
namespace App\Models;
use App\Collections\ProductCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\CollectedBy;
#[CollectedBy(ProductCollection::class)]
class Product extends Model
{
public function getEffectivePrice()
{
if ($this->discount_percentage > 0) {
return $this->price * (1 - $this->discount_percentage / 100);
}
return $this->price;
}
}
Атрибут CollectedBy спрощує персоналізацію колекцій, зберігаючи чистоту та читабельність коду у ваших Laravel-додатках