Получение данных в Laravel с использованием Eloquent и внешних ключей - PullRequest
0 голосов
/ 22 ноября 2018

Я создаю систему библиотек игр для проекта и пытаюсь реализовать функцию поиска, которая бы отображала пользовательские игры, которые они ищут.

У меня есть две модели, называемые Game и GameInformation.Это связано с тем, что многие игры имеют одинаковую информацию, то есть являются одной и той же игрой.Файлы миграции выглядят следующим образом:

GameInformation

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGameInformationTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('game_information', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('description');
            $table->string('genre');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('Game_Information');
    }
}

Game

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGamesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('games', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('info_id')->unsigned();
            $table->foreign('info_id')->references('id')->on('game_information');
            $table->enum('type', ['disc', 'cartridge']);
            $table->integer('platform_id')->unsigned();
            $table->foreign('platform_id')->references('id')->on('platforms');
            $table->integer('price');
            $table->year('year_released');
            $table->boolean('available')->default(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('Games');
    }
}

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

Панель поиска

<form class="form-inline" action="/search" method="POST" role="/search">
    {{ csrf_field() }}
    <div class="input-group">
        <input type="text" class="form-control" name="q" placeholder="Search">
    </div>
</form>

Функция поиска в SearchController

public function search() {
  $q = Input::get ( 'q' );
  if(strlen($q) == 0 || strpos($q, '%') !== false) { // For security
    return view ('home')->with('failureMsg','Nothing was found...');
  }
  $infos = GameInformation::where('title', 'like', '%' . $q .'%')->get();
  $games = array();
  foreach($infos as $info) {
    $gamesWithInfo = $info->games();
    array_push($games, array($info, $gamesWithInfo));
  }
  if (count ( $games ) > 0)
      return view ('home')->with( $games )->withQuery($q);
  else
      return view ('home')->with('failureMsg','Nothing was found...');
}

Отображение результатов поиска

<div class="card">
    <div class="card-header">Dashboard</div>
    <div class="card-body">
      <div class="container">
        <div class="row">
        </div>
          @if(!empty($failureMsg))
          <div class="alert alert-failure"> {{ $failureMsg }}</div>
          @endif
          @if(isset($games))
          HELLO
              <p> The search results for your query <b> {{ $query }} </b> are :</p>
          <h2>Games found:</h2>
          <table class="table table-striped">
              <thead>
                  <tr>
                      <th>Title</th>
                      <th>Description</th>
                  </tr>
              </thead>
              <tbody>
                  @foreach($games as $game)
                  <tr>
                      <td>{{$game(0)->title}}</td>
                      <td>{{$game(0)->description}}</td>
                  </tr>
                  @endforeach
              </tbody>
          </table>
          @endif
      </div>
    </div>
</div>

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

Также в SearchController на строке:

$infos = GameInformation::where('title', 'like', '%' . $q .'%')->get();

Я также попытался сделать это:

$infos = GameInformation::where('title', 'like', '%' . $q .'%');

Но это вернет сообщение об ошибке, где ничего не найдено.

Также модели:

Игра

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Eloquent;

class Game extends Eloquent
{
  protected $primaryKey = 'id';

  public function information() {
    return $this->belongsTo('App\GameInformation');
  }
}

GameInformation

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Eloquent;

class GameInformation extends Eloquent
{
    protected $table = 'game_information';
    protected $primaryKey = 'id';

    public function games() {
      return $this->hasMany('App\Game', 'info_id');
    }
}

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Я, похоже, решил проблему, похоже, что $ games не распознавался, поэтому, когда я возвращал представление, я изменил его на:

return view ('home')->with('gamesAndInfo', $gamesWithInfo )->withQuery($q);

И теперь он устанавливается правильно.

0 голосов
/ 22 ноября 2018

Для начала убедитесь, что значение $q - это то, что вы ожидаете, чтобы убедиться, что первое условие не срабатывает:

$q = Input::get ( 'q' );
dd($q); // temporarily to verify the value
if(strlen($q) == 0 || strpos($q, '%') !== false) {
    return view ('home')->with('failureMsg','Nothing was found...');
}

Затем убедитесь, что вы получаете правильные результаты от вашегоquery:

$infos = GameInformation::where('title', 'like', '%' . $q .'%')->get();
dd($infos); // temporarily to verify at least one item is found

Если вы проходите цикл foreach($infos as $info) хотя бы один раз, то в вашем массиве $games должен быть хотя бы один элемент.Если $games пусто, вы получите второе условие ошибки.

Еще одна проблема:

$gamesWithInfo = $info->games();

Вам необходимо получить игры.С вашим текущим кодом вы можете сделать это следующим образом:

$gamesWithInfo = $info->games()->get();

Или просто:

$gamesWithInfo = $info->games;

Но было бы лучше загрузить их:

$infos = GameInformation::with('games')
    ->where('title', 'like', '%' . $q .'%')->get();

Затем используйте:

$gamesWithInfo = $info->games;

Внутри вашего цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...