【问题标题】:Retrieving data in Laravel using Eloquent and foreign keys使用 Eloquent 和外键在 Laravel 中检索数据
【发布时间】:2018-11-22 00:58:30
【问题描述】:

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

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

游戏信息

<?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');
    }
}

【问题讨论】:

  • $info-&gt;games() 呃,devin,你有没有听说过-&gt;with() 的热切加载关系..?例如GameInformation::where('title', 'like', '%' . $q .'%')-&gt;get(); 将是 GameInformation::with('games')-&gt;where('title', 'like', '%' . $q .'%')-&gt;get();。虽然我很好奇你在GameInformation::where('title', 'like', '%' . $q .'%')-&gt;get(); 时遇到了什么错误。
  • 我没有收到任何错误,而是没有显示任何内容。我已经尝试了急切加载,并且得到了相同的结果。我在下面我刚刚发布的帖子中展示了这一点。

标签: php laravel eloquent


【解决方案1】:

首先,验证$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;

在你的循环中。

【讨论】:

    【解决方案2】:

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

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

    现在它被正确设置了。

    【讨论】:

      猜你喜欢
      • 2019-03-04
      • 1970-01-01
      • 2021-05-09
      • 2019-12-11
      • 2022-07-27
      • 2019-10-14
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多