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);
}
заставляя модель вызываться, когда некоторые функции отсутствуют