Узор Laravel для всех моделей

Я следовал за многими уроками репозитория 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, поэтому, если это необходимо, мне нужно создать хранилище для всех моделей отдельно. Есть ли способ, чтобы я мог использовать один репозиторий и внедрить модель

0

Решение

Вы можете, но я не уверен, что это хорошее решение. Я также использую какой-то шаблон репозитория во всех моих проектах 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'));
}
1

Другие решения

Я много раз видел эти уроки. Это очень сложный подход. Вполне возможно делать то, что вы хотите.

Самый простой подход заключается в следующем;

Во-первых, вы хотите создать базовый репозиторий, который будет расширяться всеми остальными репозиториями. Я использую общий для себя, который вы можете увидеть здесь: 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 будут автоматически предлагать и определять типы возвращаемых данных.

Существует также метод удаления, но вы можете переопределить его самостоятельно, если хотите.

1

По вопросам рекламы [email protected]