Laravel - Использование шаблона репозитория

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

Краткий обзор моей структуры репозитория/приложения.

app/
  Acme/
    Repositories/
      RepositoryServiceProvider.php
      Product/
        EloquentProduct.php
        ProductInterface.php
      Category/
        EloquentCategory.php
        CategoryInterface.php

Пример ProductInterface.php

<?php namespace GD\Repositories\Product;

interface ProductInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

Пример CategoryInterface.php

<?php namespace GD\Repositories\Category;

interface CategoryInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

Хорошо, поэтому простая часть использует DI для ввода зависимостей модели в контроллер.

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

Это не сработает без внедрения метода с в моем классе EloquentCategory...

public function show($slug)
{
  return Response::json($this->category->findBySlug($slug)->with('products'), 200);
}

Должен ли я создать отдельный класс службы для склеивания двух репозиториев? например позволяя следующее

public function __construct(ShopService $shop)
{
  $this->shop = $shop;
}

public function show($slug)
{
  return Response::json( $this->shop->getProductsInCategory($slug), 200 );
}

Или, альтернативно, должен ли я реализовывать метод with в моем репозитории категорий?

public function with($relation)
{
  return Category::with($relation);
}

Наконец, я понимаю, как правильно использовать шаблон репозитория?

Ответ 1

Вы передумали, репозиторий - это просто ссылка/мост между вашими controller и model, и, следовательно, контроллер использует repository class вместо model напрямую, и в этом репозитории вы можете объявить свои методы, используя model оттуда, например:

<?php namespace GD\Repositories\Category;

interface CategoryInterFace{

    public function all();

    public function getCategoriesWith($with);

    public function find($id);
}

Теперь реализуем интерфейс в классе репозитория:

<?php namespace GD\Repositories\Category;

use \EloquentCategory as Cat; // the model
class CategoryRepository implements CategoryInterFace {
    public function all()
    {
        return Cat::all();
    }

    public function getCategoriesWith($with)
    {
        return Cat::with($with)->get();
    }

    public function find($id)
    {
        return Cat::find($id):
    }
}

Чтобы использовать его в контроллере:

<?php

use GD\Repositories\Category\CategoryInterFace;

class CategoryController extends BaseController {

    public function __construct(CategoryInterFace $category)
    {
        $this->cat = $category;
    }

    public function getCatWith()
    {
        $catsProd = $this->cat->getCategoriesWith('products');
        return $catsProd;
    }

    // use any method from your category
    public function getAll()
    {
        $categories = $this->cat->all();

        return View::make('category.index', compact('categories'));
    }

}

Примечание. Оповещает IoC привязку репозитория, потому что это не ваша проблема, и вы это знаете.

Обновление: Я написал статью здесь: LARAVEL - ИСПОЛЬЗОВАНИЕ РЕПОЗИТАРНОГО ОБРАЗЦА.

Ответ 2

Существует очень простой способ сделать это, и он подробно исследуется в этой ссылке

http://heera.it/laravel-repository-pattern#.U6XhR1cn-f4

Я искал точное решение и хорошо работает до сих пор

поэтому для вас было бы объявить это в вашем коде репозитория

public function __construct(\Category $category)
{
    $this->category = $category;
} 
public function getAllUsers()
{
    return $this->category->all();
}

public function __call($method, $args)
{
    return call_user_func_array([$this->category, $method], $args);
}

заставляя модель вызываться, когда некоторые функции отсутствуют