Допустим, у нас есть 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