使用雄辩和外键在Laravel中检索数据

时间:2018-11-22 00:58:30

标签: php laravel eloquent

我正在为一个项目制作一个游戏库系统,并试图实现一个搜索功能,该功能将显示用户正在搜索的用户游戏。

我有两个模型,分别称为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');
    }
}

游戏

<?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 :(得分:0)

首先,请验证$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...');
}

然后确认您从查询中获得了正确的结果:

$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;

在循环中

答案 1 :(得分:0)

我似乎已经解决了这个问题,似乎因为$ games未被识别,所以当我返回视图时,将其更改为:

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

现在已正确设置。

相关问题