Я пытаюсь изучить шаблон репозитория и, похоже, немного запутался в том, как я могу использовать этот шаблон репозитория при энергичных загрузках и сохранить логику 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 для ввода зависимостей модели в контроллер.
перечислить все категории со связанными продуктами сложнее, поскольку я больше не работаю с красноречивой моделью. Я работаю с интерфейсом, который не раскрыл всех красноречивых методов.
Это не сработает без применения метода in в моем классе 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); }
Наконец, я понимаю, как правильно использовать шаблон репозитория?
Вы передумали, репозиторий – это просто ссылка / мост между вашим controller
и model
и, следовательно, контроллер использует класс repository
вместо 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 – ИСПОЛЬЗОВАНИЕ РЕПОЗИТАРНОГО ОБРАЗЦА .
Существует очень простой способ сделать это, и он подробно исследуется в этой ссылке
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); }
заставляя модель вызываться, когда некоторые функции отсутствуют