Лучшая практика Laravel — запрос

#php #laravel #laravel-5

#php #laravel #laravel-5

Вопрос:

Мне нужно передать некоторые данные в мое представление. У меня есть две модели: пользовательская и модель подсказок.

Пользовательская модель имеет метод, который возвращает user hasMany(подсказка::Class), а модель Tip имеет метод, который возвращает, что подсказка принадлежит(User::class).

Я создаю страницу профиля для пользователя и использую привязку модели маршрута для возврата модели пользователя при доступе к профилю.

 public function tipsterProfileShow(User $tipster)
{
  if (!$tipster->isTipster())
  {
    return redirect()->route('home');
  }

  return view('profile.index')->with([
    'tipster' => $tipster,
    'tips' => $tipster->tips(),
  ]);
}
  

Я хочу отобразить некоторые данные, такие как количество правильных подсказок, которые указаны в столбце статус в таблице подсказок.

На данный момент в представлении блейда я использую

 {{$tips->where('status','Won')->count()}}
  

Я чувствую, что это не лучшая практика, но я могу ошибаться.

Было бы лучше сделать что-то вроде приведенного ниже?

 public function tipsterProfileShow(User $tipster)
{
  if (!$tipster->isTipster())
  {
    return redirect()->route('home');
  }
  return view('profile.index')->with([
    'tipster' => $tipster,
    'tips' => $tipster->tips(),
    'wins' => $tipster->tips()->where('status', 'Won')->count()
  ]);
}
  

Таким образом, я бы скрывал запросы от просмотра. Я действительно новичок в laravel и «лучшей практике», поэтому пытаюсь получить несколько советов.

Ответ №1:

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

Вкратце: ДА! То, что вы делаете, является отличным первым шагом к разделению вашего кода по логике. Ваши представления должны отвечать за отображение данных, а ваши контроллеры — за обработку данных в представлениях. Должны ли ваши контроллеры на самом деле отвечать за вычисление данных — это другая тема, которая постоянно обсуждается.

Тем не менее, вы могли бы свести это к одной строке в контроллере, если применить немного другую логику:

 public function tipsterProfileShow(User $tipster)
{
  return view('profile.index', compact('tipster'));
}
  

Первый шаг — добавить метод в вашу User модель, что-то вроде этого:

 public function winCount()
{
    return $this->tips()->where('status', 'Won')->count();
}
  

Теперь вы можете получить доступ $tipster->winCount() из своего представления. Вы также можете получить доступ $tipster->tips() сразу, на ваш взгляд — большинство согласится, что это совершенно нормально.

Второй шаг заключается в извлечении вызова перенаправления для не-подсказчиков в промежуточное программное обеспечение, о котором вы можете прочитать здесь:https://laravel.com/docs/5.3/middleware

Есть дальнейшие шаги, которые вы могли бы предпринять оттуда, но это хорошая отправная точка. Удачи! 🙂

Комментарии:

1. Именно тот ответ, который я искал. Большое вам спасибо, я воспользуюсь вашим советом и реализую его.

Ответ №2:

Я посоветую вам создать POPO (обычный старый объект PHP), который будет содержать полное описание пользователя, более синонимичное профилю пользователя.

Модель в laravel представляет строку в таблице, и она будет лениво загружать любые связанные с ней отношения.

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

Возьмем ниже в качестве примера:

 Class UserPorfile{
  private $id;
  private $username;
  private $tips;

  public function setId($id){
     $this->id = $id;
  }

  public function getId(){
     return $this->id;
  }

  public function setUsername($username){
      $this->username = $username;
  }

  public function getUsername(){
     return $this->username;
  }

  public function setTips(array $tips){
     $this->tips = $tips;
  }

  public function getTips(){
     return $this->tips;
  }
}
  

передача объекта этого класса на ваш взгляд кажется намного лучше

Ответ №3:

Да, вы правы. Учитывая, что вы пытаетесь следовать шаблону разработки программного обеспечения MVC, вам следует избегать использования бизнес-логики в вашем представлении.

Эта строка кода:

 {{$tips->where('status','Won')->count()}}
  

на самом деле делает 2 вещи:

  1. Запрашивайте модель для всех объектов с определенными критериями
  2. Подсчитайте результат

Следуя принципам MVC, именно ваш контроллер должен отправлять команды модели, а не представлению.

Удачи!