Найти в Дзене
Jh5.Studio

Используем Трейты для Laravel Eloquent связей

Допустим, у нас есть Post модель, которая выглядит примерно так:

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Post
*
* @package App
*/
class Post extends Model
{
/**
* @return string
*/
public function getTitle()
{
return $this->getAttribute('title');
}

/**
* @param string $title
* @return $this
*/
public function setTitle(string $title)
{
$this->setAttribute('title', $title);

return $this;
}

/**
* @return string
*/
public function getPost()
{
return $this->getAttribute('post');
}

/**
* @param string $post
* @return $this
*/
public function setPost(string $post)
{
$this->setAttribute('post', $post);

return $this;
}

/**
* @param Account $account
* @return $this
*/
public function setAccount(Account $account)
{
$this->account()->associate($account);

return $this;
}

/**
* @return Account|null;
*/
public function getAccount()
{
return $this->getAttribute('account');
}

/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function account()
{
return $this->belongsTo(Account::class, 'account_id', 'id');
}
}

У нас есть некоторые методы, определенные для свойств Post модели, и некоторые для связи с моделью Account.

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

Traits (Трейты)

Я начну с Php.net документации:

Traits - это механизм повторного использования кода в языках с одним наследованием, таких как PHP. Trait предназначен для уменьшения некоторых ограничений единого наследования, позволяя разработчику повторно использовать наборы методов свободно, в нескольких независимых классах, живущих в разных иерархий классов. Семантика сочетания трейтов и классов определяется таким образом, чтобы уменьшить сложность и избежать типичных проблем, связанных с множественным наследованием и примесями (mixins).

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

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

<?php

namespace App;

/**
* Class HasAccountTrait
*
* @package App
*/
trait HasAccountTrait
{
/**
* @param Account $account
* @return $this
*/
public function setAccount(Account $account)
{
$this->account()->associate($account);

return $this;
}

/**
* @return Account|null;
*/
public function getAccount()
{
return $this->getAttribute('account');
}

/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function account()
{
return $this->belongsTo(Account::class, 'account_id', 'id');
}
}

Затем мы изменим нашу Post модель, чтобы использовать наш трейт, она будет выглядеть таким образом:

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Post
*
* @package App
*/
class Post extends Model
{
use HasAccountTrait;

/**
* @return string
*/
public function getTitle()
{
return $this->getAttribute('title');
}

/**
* @param string $title
* @return $this
*/
public function setTitle(string $title)
{
$this->setAttribute('title', $title);

return $this;
}

/**
* @return string
*/
public function getPost()
{
return $this->getAttribute('post');
}

/**
* @param string $post
* @return $this
*/
public function setPost(string $post)
{
$this->setAttribute('post', $post);

return $this;
}
}

Вывод:

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

Хотите новых статей про Laravel? Заходите на наш сайт: https://jh5.ru/news