• Время чтения ~7 мин
  • 08.09.2023

Lift - это пакет, который улучшает ваши красноречивые модели в Laravel.

Он позволяет создавать открытые свойства в красноречивых моделях, которые соответствуют схеме таблицы. Это упрощает чтение моделей и работу с ними в любой интегрированной среде разработки.

Он предоставляет простой способ настройки ваших моделей, уделяя особое внимание простоте и удобству использования с использованием атрибутов PHP 8.

Пакет зависит от работы Eloquent Events. Это означает, что пакет легко вписывается в ваш проект без каких-либо серьезных изменений (если вы не отключили запуск событий).

В этом посте давайте углубимся в Lift и узнаем обо всех функциях, которые он предоставляет.

Установка Laravel Lift Вы можете установить пакет через composer:

Чтобы начать использовать Lift

composer require wendelladriel/laravel-lift

, вам нужно добавить эту черту Lift в свои красноречивые модели, и вы готовы к работе.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;
}

Особенности

По умолчанию, когда вы добавляете Lift признак в свои красноречивые модели, вы можете создавать для них открытые свойства, что упрощает их понимание и работу в любой среде IDE.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    public $id;

    public $name;

    public $price;
}

Волшебство происходит, когда вы начинаете использовать атрибуты, предоставляемые пакетом.

Атрибуты класса Lift предоставляет атрибут, DB который можно использовать для определения соединения, таблицы

Lift предоставляет атрибут, DB который можно использовать для определения соединения, таблицы

и меток времени модели.

Без лифта

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    public $timestamps = false;

    protected $connection = 'mysql';

    protected $table = 'custom_products_table';

    // ...
}

С лифтом

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\DB;
use WendellAdriel\Lift\Lift;

#[DB(connection: 'mysql', table: 'custom_products_table', timestamps: false)]
final class Product extends Model
{
    use Lift;
    // ...
}

Relationship Attributes

Lift предоставляет атрибуты для определения связей между моделями, поэтому вместо того, чтобы определять их с помощью методов, вы можете определить их как атрибуты. Все атрибуты отношений принимают те же параметры, что и методы.

Без лифта

// Post.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

final class Post extends Model
{
    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }
    // ...
}
// Comment.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class Comment extends Model
{
    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }
    // ...
}

С лифтом

// Post.php
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Relations\HasMany;
use WendellAdriel\Lift\Lift;

#[HasMany(Comment::class)]
final class Post extends Model
{
    use Lift;
    // ...
}
// Comment.php
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Relations\BelongsTo;
use WendellAdriel\Lift\Lift;

#[BelongsTo(Post::class)]
final class Comment extends Model
{
    use Lift;
    // ...
}

Вы можете проверить все доступные атрибуты отношений в документации.

Отношения будут работать так же, как если бы вы определили их с помощью методов.

Property Attributes

Cast Attribute

Lift предоставляет атрибут, Cast который можно использовать для определения приведения свойств модели. Помимо приведения значений, он также позволяет вводить свойства.

Без лифта

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
        'active' => 'boolean',
        'expires_at' => 'immutable_datetime',
    ];
}

С лифтом

use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Cast('string')]
    public string $name;

    #[Cast('float')]
    public float $price;

    #[Cast('boolean')]
    public bool $active;

    #[Cast('immutable_datetime')]
    public CarbonImmutable $expires_at;
}

Lift Column Attribute

Lift предоставляет атрибут, Column который можно использовать для настройки имени столбца свойств модели и определения значений по умолчанию.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Cast('string')]
    #[Column('product_name')]
    public string $name;

    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
}

В приведенном выше name примере свойство будет сопоставлено со столбцомproduct_name, а price свойство будет сопоставлено со столбцом product_price со значением 0.0по умолчанию .

Вы даже можете передать имя функции в значение по умолчанию, которое будет вызываться при сохранении свойства в базе данных.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Cast('string')]
    #[Column('product_name')]
    public string $name;

    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;

    #[Cast('float')]
    #[Column(default: 'generatePromotionalPrice')]
    public float $promotional_price;

    public function generatePromotionalPrice(): float
    {
        return $this->price * 0.8;
    }
}

Заполняемый атрибут

При использовании признака Lift все атрибуты вашей модели имеют значение guarded. С помощью атрибута можно определить, Fillable какие свойства могут быть назначены массово.

Без лифта

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    protected $fillable = [
        'name',
        'price',
    ];
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
    ];
}

С лифтом

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    public float $price;
}

Hidden Attribute

Lift предоставляет атрибут, Hidden который можно использовать для скрытия свойств модели при ее преобразовании в массив или JSON.

Без лифта

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    protected $fillable = [
        'name',
        'price',
        'active',
    ];
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
        'active' => 'boolean',
    ];
    protected $hidden = [
        'active',
    ];
}

С лифтом

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Hidden;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    public float $price;

    #[Hidden]
    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}

Immutable Attribute

Lift предоставляет атрибут, Immutable который можно использовать, чтобы сделать свойства неизменяемыми. Это означает, что после создания модели свойство не может быть изменено. Если вы попытаетесь изменить его, будет брошеноWendellAdriel\Lift\Exceptions\ImmutablePropertyException.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Immutable;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Immutable]
    #[Fillable]
    #[Cast('string')]
    public string $name;
}
$product = Product::query()->create([
    'name' => 'Product 1',
]);
$product->name = 'Product 2';
$product->save(); // Throws an WendellAdriel\Lift\Exceptions\ImmutablePropertyException

PrimaryKey Attribute

Lift предоставляет атрибут, PrimaryKey который можно использовать для настройки первичного ключа модели.

Без лифта

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    public $incrementing = false;

    protected $primaryKey = 'uuid';

    protected $keyType = 'string';
    // ...
}

С лифтом

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\PrimaryKey;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[PrimaryKey(type: 'string', incrementing: false)]
    #[Cast('string')]
    public string $uuid;
    // ...
}

Rules Attribute

Lift предоставляет атрибут, Rules который можно использовать для определения правил проверки свойств модели.

Проверки могут быть установлены так же, как и в Laravel Form Request, и вы даже можете установить пользовательские сообщения для каждого правила.

⚠️ Правила будут проверены только при сохранении модели (создании или обновлении)

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;

    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}

Атрибут наблюдения

По умолчанию Eloquent уже инициирует события при создании, обновлении, удалении модели и т. д. Но это общее событие, и иногда вам нужно инициировать определенное событие при изменении свойства. Вот тут-то и Watch появляется атрибут.

Можно определить пользовательское событие, которое будет запускаться при изменении свойства. Событие получит в качестве параметра обновленный экземпляр модели.

// Product.php
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Watch;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    #[Watch(PriceChangedEvent::class)]
    public float $price;

    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}
// PriceChangedEvent.php
final class PriceChangedEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public Product $product,
    ) {
    }
}

Методы

Помимо всех атрибутов, предоставляемых пакетом, он также предоставляет некоторые методы, которые можно использовать для получения дополнительной информации о ваших моделях.

customColumns()

Он вернет массив со всеми пользовательскими столбцами, которые вы определили в своей модели.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Cast('string')]
    #[Column('product_name')]
    public string $name;

    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
}
Product::customColumns();

// WILL RETURN
[
    'name' => 'product_name',
    'price' => 'product_price',
]

defaultValues()

Он вернет массив со всеми свойствами, для которых определено значение по умолчанию. Если значением по умолчанию является функция, вместо результата функции будет возвращено имя функции, так как это статический вызов.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Cast('string')]
    #[Column('product_name')]
    public string $name;

    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;

    #[Cast('float')]
    #[Column(default: 'generatePromotionalPrice')]
    public float $promotional_price;

    public function generatePromotionalPrice(): float
    {
        return $this->price * 0.8;
    }
}
Product::defaultValues();

// WILL RETURN
[
    'price' => 0.0,
    'promotional_price' => 'generatePromotionalPrice',
]

immutableProperties()

Он вернет массив со всеми неизменяемыми свойствами.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Immutable;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Immutable]
    #[Fillable]
    #[Cast('string')]
    public string $name;
}
Product::immutableProperties();

// WILL RETURN
[
    'name',
]

validationMessages()

Он вернет массив со всеми проверочными сообщениями, определенными в модели.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;

    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}
Product::validationMessages();

// WILL RETURN
[
    'name' => [],
    'price' => [],
    'active' => [
        'required' => 'You must set the active status for the product',
    ],
]

validationRules()

Он вернет массив со всеми правилами проверки, которые вы определили в своей модели.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;

    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}
Product::validationRules();

// WILL RETURN
[
    'name' => ['required', 'string', 'max:255'],
    'price' => ['required', 'numeric', 'min:0.0'],
    'active' => ['required', 'boolean'],
]

watchedProperties()

Он вернет массив со всеми свойствами с определенным пользовательским событием.

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Watch;
use WendellAdriel\Lift\Lift;

final class Product extends Model
{
    use Lift;

    #[Cast('int')]
    public int $id;

    #[Fillable]
    #[Cast('string')]
    public string $name;

    #[Fillable]
    #[Cast('float')]
    #[Watch(PriceChangedEvent::class)]
    public float $price;

    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}
Product::watchedProperties();

// WILL RETURN
[
    'price' => PriceChangedEvent::class,
]

Заключение

Lift — это пакет, который привносит в Eloquent некоторые функции таких инструментов, как Doctrine, Spring и Entity Framework.

Это делает ваши модели более легкими для чтения и понимания, а также более чистым внешним видом, используя преимущества атрибутов PHP 8.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297