Решение для репозитория Laravel (всего 30 строк кода)

  • 17 сентября, 16:00
  • 3444
  • 0

30-строчный фрагмент скрипта может наконец обеспечить хорошее решение для шаблона репозитория в приложениях Laravel.

Ссылка на страницу Github

Проблема

Laravel предоставляет прекрасный способ запроса вашей базы данных с помощью Eloquent, Object Relational Mapping. В тот момент, когда ваш проект становится больше, возникает проблема. Разница между сущностями и моделями начинает расплываться. Позвольте привести пример:

У нас есть два метода, один называется findByName и один называется concatName,

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'products';
    /**
     * Find published product by name
     * @param  string $name
     * @return Product
     */
    public function findByName(string $name): Product
    {
        return $this->whereName($name)
                    ->whereIsPublished(1)
                    ->first();
    }
    /**
     * Say we want to concat the name and a category name
     * @return string 
     */
    public function concatName(): string
    {
        return $this->attributes['name'] . ' - ' . $this->attributes['category_name'];
    }
}

То, что мы на самом деле здесь делаем, - это смешивание методов для получения (наборов) продуктов с методами для экземпляров 1 Продукта. 

Гораздо чище подход будет разделить их на 2 разных класса. Один для получения экземпляров и коллекций моделей и один для определения самой модели. Вы можете назвать это шаблоном хранилища.

Решение для репозитория Laravel (всего 30 строк кода)

Разделение на 2 класса

Есть несколько библиотек для Laravel, чтобы начать использовать шаблон репозитория. Для меня огромным недостатком является то, что вы не можете использовать функции Eloquent в своих репозиториях. Поскольку Eloquent - это огромная причина, по которой я использую Laravel, я все же хотел иметь возможность использовать Eloquent в репозиториях для получения моделей. 

Решение

Я создал очень простой кусок кода, который включает все функции Eloquent в ваших репозиториях. Таким образом, вы можете использовать шаблон хранилища таким образом, чтобы это было просто и содержало ваши модели и ваши хранилища в чистоте! Репозиторий с использованием laravel-repositories будет выглядеть так:

<?php

namespace App\Repositories;

use App\Models\Product;
use MrAtiebatie\Repository;
use Illuminate\Database\Eloquent\Model;

/**
 * Product repository
 */
class ProductRepository extends Model
{
    use Repository;
    /**
     * The model being queried.
     *
     * @var \Illuminate\Database\Eloquent\Model
     */
    protected $model;
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->model = app(Product::class);
    }
    /**
     * Find published products by SKU
     * @param  {int} $sku
     * @return {Product}
     */
    public function findBySku(int $sku): Product {
        return this->whereIsPublished(1)
                   ->whereSku($sku)
                   ->first();
    }
}

Используя черту Repository и $model свойство, laravel-repositories знает, какую модель запрашивать и где использовать Eloquent, а где использовать собственные методы хранилища. 

С этим определением репозитория мы можем теперь использовать его в наших контроллерах, заданиях, командах и т.д .:

<?php

/**
 * In your routes/web.php
 */

$router->get('/', function (\App\Repositories\ProductRepository $productRepo) {

    // Use any Eloquent feature directly
    $productRepo->all()->dd();

    // Use your custom repository methods
    echo $productRepo->findBySku(12345)->name;

    // You can even query relations
    echo $productRepo->first()->category;
});


0 комментариев
Сортировка:
Добавить комментарий

IT Новости

Смотреть все