Я следовал за многими уроками репозитория Laravel и msot урока схожим. Одна из ссылок ниже
https://itsolutionstuff.com/post/laravel-5-repository-pattern-tutorial-from-scratchexample.html
Шаг 1: Создать интерфейс
На первом этапе мы должны создать интерфейс, прежде чем создавать каталог Repositories (app / Repositories) в папке приложения. Также нам нужно создать папку User (app / Repositories / User) внутри папки Repositories.
Хорошо, теперь сначала мы создадим UserInterface в каталоге User, поэтому сначала создайте файл UserInterface.php и поместите приведенный ниже код в этот файл:
Приложение / Хранилище / User / UserInterface.php
namespace App\Repositories\User;
interface UserInterface {
public function getAll();
public function find($id);
public function delete($id);
}
Шаг 2: Создать репозиторий
Хорошо, на этом шаге мы создадим UserRepository.php
Для записи логина базы данных, в этом файле мы напишем код нашей базы данных. Итак, сначала создайте UserRepository.php
файл в каталоге пользователя и введите ниже код.
Приложение / Хранилище / User / UserRepository.php
namespace App\Repositories\User;
use App\Repositories\User\UserInterface as UserInterface;
use App\User;
class UserRepository implements UserInterface
{
public $user;
function __construct(User $user) {
$this->user = $user;
}
public function getAll()
{
return $this->user->getAll();
}
public function find($id)
{
return $this->user->findUser($id);
}
public function delete($id)
{
return $this->user->deleteUser($id);
}
}
Шаг 3: Создать провайдера услуг
На этом этапе мы должны создать поставщика услуг для привязки UserInterface
а также UserRepository
учебный класс. так что давайте создадим UserRepoServiceProvide
.php` файл в папке пользователя и положить следующий код:
Приложение / Хранилище / User / UserRepoServiceProvide.php
namespace App\Repositories\User;
use Illuminate\Support\ServiceProvider;
class UserRepoServiceProvide extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('App\Repositories\User\UserInterface', 'App\Repositories\User\UserRepository');
}
}
Теперь нам нужно добавить сервер в файл app.php, поэтому добавьте UserRepoServiceProvide в config / app.php и добавьте нижнюю строку.
конфиг / app.php
return [
....
'providers' => [
......,
App\Repositories\User\UserRepoServiceProvide::class,
]
....
]
Шаг 4. Создание пользовательской модели
Думаю, у нас уже есть Модель пользователя, поэтому вам просто нужно добавить функции getAll (), findUser () и deleteUser (). Но вы также можете пройти ниже код тоже. Итак, давайте поместим ниже код на вашей модели.
Приложение / User.php
приложение namespace;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function getAll()
{
return static::all();
}
public function findUser($id)
{
return static::find($id);
}
public function deleteUser($id)
{
return static::find($id)->delete();
}
}
Шаг 5: Использование в контроллере
Теперь мы готовы использовать наш шаблон репозитория в нашем контроллере. Итак, давайте добавим приведенный ниже код в ваш файл UserController.php.
приложение / Http / Контроллеры / UserController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repositories\User\UserInterface as UserInterface;
class UserController extends Controller
{
public function __construct(UserInterface $user)
{
$this->user = $user;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$users = $this->user->getAll();
return view('users.index',['users']);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$user = $this->user->find($id);
return view('users.show',['user']);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function delete($id)
{
$this->user->delete($id);
return redirect()->route('users');
}
}
Теперь, наконец, просто выполните команду ниже, потому что мы должны автоматически загружать класс.
обновление композитора
php artisan optimize
Мой вопрос состоит в том, что большинство пользовательских руководств внедряют пользовательскую модель в UserRepository, поэтому, если это необходимо, мне нужно создать хранилище для всех моделей отдельно. Есть ли способ, чтобы я мог использовать один репозиторий и внедрить модель
Вы можете, но я не уверен, что это хорошее решение. Я также использую какой-то шаблон репозитория во всех моих проектах Laravel, но я устанавливаю его по-другому.
у меня есть BaseRepository
со всеми моими стандартными функциями следующим образом:
<?php
namespace App\Repositories;
use Carbon\Carbon;
class BaseRepository {
public $model;
public function __construct($model){
$this->model = $model;
}
public function all(){
return $this->model->all();
}
public function getById($id){
return $this->model->findorFail($id);
}
public function store($model){
$model->created_at = Carbon::now();
return $model->save();
}
public function update($model){
$model->updated_at = Carbon::now();
return $model->save();
}
public function destroy($model){
return $model->delete();
}
}
Таким образом, в моем контроллере, если мне нужны только базовые функции (те, что в моем BaseRepository), я делаю это:
use App\Models\MyModel;
use App\Repository\BaseRepository;
class XXX extends Controller {
protected MyModelRepository;
public function __construct(BaseRepository $baseRepository){
$this->MyModelRepository = $baseRepository;
}
}
Это может соответствовать вашим потребностям, но я не думаю, что это хороший способ сделать это, потому что вам могут понадобиться некоторые специфические функции в зависимости от ваших моделей. Итак, я создаю выделенные репозитории (по одному для каждой модели) следующим образом:
<?php
namespace App\Repository;
use App\Model\Maj;
class MajRepository extends BaseRepository {
public function __construct(Maj $maj){
$this->model = $maj;
}
public function all(){
return $this->model->with('medias')->with('plugins')->get();
}
public function getById($id){
return $this->model->with('medias')->with('plugins')->findorFail($id);
}
}
Таким образом, этот конкретный репозиторий, связанный с моей конкретной моделью, расширяет BaseRepository и позволяет использовать все функции BaseRepositories. Но он также может иметь свои специфические функции, как вы можете видеть. Тогда я называю это так в моих контроллерах:
<?php
namespace App\Http\Controllers;
use App\Model\Maj;
use App\Repository\MajRepository;
use Illuminate\Http\Request;
use Carbon\Carbon;
class WpMajController extends Controller {
protected $majRepository;
public function __construct(MajRepository $majRepository){
$this->majRepository = $majRepository;
}
/**
* Permet d'afficher la liste des suivi de mises à jour WP
* @return view
*/
public function index(){
$majs = $this->majRepository->all();
return view('wpMaj.index', compact('majs'));
}
Я много раз видел эти уроки. Это очень сложный подход. Вполне возможно делать то, что вы хотите.
Самый простой подход заключается в следующем;
Во-первых, вы хотите создать базовый репозиторий, который будет расширяться всеми остальными репозиториями. Я использую общий для себя, который вы можете увидеть здесь: https://github.com/ollieread/toolkit/blob/master/src/Repositories/BaseRepository.php (Я связываю, потому что это довольно большой). Важным моментом является следующее;
abstract class BaseRepository {
protected $model;
protected function make() {
return new $this->model;
}
// rest of the code here
}
Теперь я могу создать себе UserRepository
следующее;
class UserRepository extends BaseRepository {
protected $model = User::class;
public function getAll(): Collection {
return $this->make()->newQuery()->get();
}
}
Там нет возни с интерфейсами (которые 9 раз из 10 не нужны), что означает, что вам не нужно связывать это с IoC. Вы можете напечатать подсказку UserRepository
и получить экземпляр.
Я также не внедряю модель, потому что, проще говоря, вам нужно знать только название класса. Когда вам действительно нужен экземпляр, вы можете запустить $this->make()
,
Примечания о моем BaseRepository
С помощью чудесных магических методов вы можете назвать такие вещи, как getOneById($id)
а также getByCategoryId($categoryId)
, не определяя методы самостоятельно.
getOneById($id) => getOneBy('id', $id)
getByCategoryId($categoryId) => getBy('category_id', $categoryId)
Однако, если вы собираетесь часто использовать эти методы, я бы всегда предлагал добавить их в докблок. Так, например, UserRepository
станет;
/**
* @method User make()
* @method null|User getOneById(int $id)
* @method Collection getBySurname(string $surname)
*/
class UserRepository extends BaseRepository {
protected $model = User::class;
public function getAll(): Collection {
return $this->make()->newQuery()->get();
}
}
Таким образом, IDE будут автоматически предлагать и определять типы возвращаемых данных.
Существует также метод удаления, но вы можете переопределить его самостоятельно, если хотите.