Как использовать одну индексную функцию для двух разных контроллеров? - PullRequest
0 голосов
/ 10 июня 2019

Я пытаюсь закодировать сайт социальной сети, такой как Facebook, в Laravel 5.8.У меня в /home и в /profile тот же список ваших друзей, но два разных контроллера (HomeController & ProfileController).Я не хочу копировать вставить один и тот же код для двух разных контроллеров.Как я могу решить эту проблему, поэтому я должен использовать свой код только один раз?

HomeController.php

public function index()
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();
        foreach ($friendsID as $friendID)
            $friends[] = User::find($friendID->person2);

        return view('home')->with('friends', $friends);
    }

ProfileController.php

public function index()
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();
        foreach ($friendsID as $friendID)
            $friends[] = User::find($friendID->person2);

        return view('profile')->with('friends', $friends);
    }

В моем файле web.php есть мои маршруты.

Route::get('/home', 'HomeController@index');
Route::get('/profile', 'ProfileController@index');

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

@if(count($friends) > 0)
    @foreach($friends as $friend)
        <ul>
            <li>
                <a href="/profile/{{$friend->id}}">{{$friend->firstname . ' ' . $friend->lastname}}</a>
                <a class="text-danger"
                   href="/removeFriend/{{Auth::user()->id . '/' . $friend->id}}">[unfriend]</a>
            </li>
        </ul>
    @endforeach
@else
    <p>No friends available</p>
@endif

Как выМожно видеть, что у меня один и тот же код в двух разных контроллерах.Это не очень хорошее решение.Можете ли вы дать мне совет, как я могу написать его, чтобы он у меня был только один раз?

Ответы [ 4 ]

1 голос
/ 10 июня 2019

Я не знаю, почему мой ответ был удален администратором здесь .. Но здесь он снова. View Composer идеально подходит для этой ситуации.И вы можете зарегистрировать композитора в методе boot либо из AppServiceProvider, либо вы можете создать своего собственного поставщика услуг и зарегистрировать его в массиве config/app.php providers.

View::composer(
    ['home', 'profile'],
    'App\Http\View\Composers\YourViewComposer'
);

иМетод compose использует тот же код:

/**
* Bind data to the view.
*
* @param  View  $view
* @return void
*/
public function compose(View $view)
{
    $friends = [];
    $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();

    foreach ($friendsID as $friendID)
    {
       $friends[] = User::find($friendID->person2);
    }

    $view->with('friends', $friends);
}
0 голосов
/ 10 июня 2019

Я думаю, вы могли бы создать хранилище для запросов к БД, и вы можете использовать его с любого контроллера или класса.Например:

FriendRepository

<?php

namespace App\Repositories;

class FriendRepository
{
    public function getAll($user_id)
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')
                                        ->where('person1', $user_id)
                                        ->get();
        foreach ($friendsID as $friendID) {
            $friends[] = User::find($friendID->person2);  
        }

        return friends;
    }
}

А затем в контроллерах:

HomeController.php

<?php

namespace App\Http\Controllers;

use App\Repositories\FriendRepository;
use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
    * @var FriendRepository
    */
    private $friend_repository;

    public function __construct(FriendRepository $friend_repository)
    {
        $this->friend_repository = $friend_repository;
    }

    public function index()
    {
        $friends = $this->friend_repository->getAll(Auth::user()->id);

        return view('home')->with('friends', $friends);
    }
}

ProfileController.php

<?php

namespace App\Http\Controllers;

use App\Repositories\FriendRepository;
use Illuminate\Http\Request;

class ProfileController extends Controller
{
    /**
    * @var FriendRepository
    */
    private $friend_repository;

    public function __construct(FriendRepository $friend_repository)
    {
        $this->friend_repository = $friend_repository;
    }

    public function index()
    {
        $friends = $this->friend_repository->getAll(Auth::user()->id);

        return view('home')->with('friends', $friends);
    }
}

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

0 голосов
/ 10 июня 2019

Почему нельзя сделать два разных Routes, указывающих на одно и то же действие контроллера?

Как,

Route::get('/home', 'ProfileController@index'); Route::get('/profile', 'ProfileController@index');

В чем проблема с этим

0 голосов
/ 10 июня 2019

Попробуйте вызвать метод index из другого controller:

use ProfileController;

class HomeController {
    public function index()
    {
         ProfileController::index();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...