【问题标题】:How to use Eloquent to retrieve data from two different tables如何使用 Eloquent 从两个不同的表中检索数据
【发布时间】:2019-12-09 05:00:18
【问题描述】:

我正在设置一个系统来检查用户是否向其他用户发送了消息。

MessagesController.php

use App\Message;
use App\User;

class MessagesController extends Controller
{
    public function index()
    {
        return view('admin.messages')->with('messages', Message::all())
                                     ->with('users', User::all());

    }

消息迁移有以下数据:

Schema::create('messages', function (Blueprint $table) {
    $table->increments('id');
            $table->integer('from');
            $table->integer('to');
            $table->mediumText('text');
            $table->integer('status');
            $table->timestamps();
});

还有web.php

Route::get('/admin/messages', [
        'uses' => 'MessagesController@index',
        'as' => 'messages'
    ]);

所以想法是显示一个带有消息数据的面板,显示:

<tbody>
    <tr>
        @foreach ($messages as $message)

        <td>
            {{ $message->from}}
        </td>
        <td>
            {{ $message->to}}
        </td>
        <td>
            {{ $message->text}}
        </td>
        <td>
            {{ $message->status}}
        </td>
        <td>
            {{ $message->created_at}}
        </td>

        @endforeach
    </tr>
</tbody>

这会正确加载消息表中的所有信息。但是,它将按应有的方式显示“发件人”和“发件人”以及 ID。

我希望通过 Message 表和 Users 表之间的关系填充该表,而不是用户的 ID,而是用户的名称。

我错过了什么?

【问题讨论】:

  • from and too 用户 id 对吗?
  • @mrhn 没错,'from' 和 'to' 都是用户 ID

标签: php laravel laravel-5 eloquent relationship


【解决方案1】:

首先,您需要定义您的relationships。看起来User 有很多Messages,所以:

Message.php

public function sender()
{
    return $this->belongsTo(User::class, 'from');
}

public function receiver()
{
    return $this->belongsTo(User::class, 'to');
}

注意:这里我使用两个带有自定义外键的belongsTo relationships,这是因为 Laravel 默认会查找 {model}_id 列,但这样 Laravel 会知道要搜索的列。

然后在您的控制器中,您可以返回您的消息,但 Eager Loading 您需要的关系才能在您的视图中显示它们:

use App\Message;
use App\User;

class MessagesController extends Controller
{
    public function index()
    {
        $messages = Message::with(['sender', 'receiver'])->get();

        return view('admin.messages')->with('messages', $messages);

    }
}

那么在你看来:

<tbody>
<tr>
    @foreach ($messages as $message)
        <td>
            {{ $message->sender->name}}
        </td>
        <td>
            {{ $message->receiver->name}}
        </td>

        // ...

    @endforeach
</tr>
</tbody>

观察

鉴于主键是正整数,请将您的外键类型更新为:

Schema::create('messages', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('from'); // <-----
        $table->unsignedInteger('to');  // <------
        $table->mediumText('text');
        $table->integer('status');
        $table->timestamps();
    });

这将帮助您避免将来遇到一些麻烦。此外,在 Laravel 5.8 中,默认情况下主键是大增量。所以如果你使用这些,你的外键应该是这样的:$table-&gt;unsignedBigIncrement('column_name');

【讨论】:

  • 我已经按照你的建议完成了,但我在 messages.blade.php 上收到了 ErrorException (E_ERROR) Trying to get property of non-object
  • 原来我有一个未定义关系的表条目(“to”列中有一个 ID 为 1 的用户,而 User 表中没有 ID 为 1 的用户)。已修复,现在可以使用了,感谢您的帮助,现在更清楚如何通过 Laravel 方式访问这些数据了
【解决方案2】:

在您的消息模型中,您必须定义关系。我们定义 from 和 to 关系,这些将需要一个额外的参数来定义键名是什么,因为它不是您遵循的 Laravel 标准的一部分。

public class Message
{
    public function from()
    {
        return $this->belongsTo(User::class, 'from');
    }

    public function to()
    {
        return $this->belongsTo(User::class, 'to');
    }
}

完成此操作后,您将能够执行类似的操作。

public function index()
{
    return view('admin.messages')->with('messages', Message::all())
}

如果像 $message->from 这样访问用户,你会得到一个对象。如果您访问该方法,您将获得查询生成器,例如 $message->from()。

现在您可以在刀片模板中使用它。

<tbody>
  <tr>
    @foreach ($messages as $message)
      <td>
        {{ $message->from->name}}
      </td>
      <td>
        {{ $message->to->name}}
      </td>

      ....
    @endforeach
  </tr>
</tbody>

【讨论】:

  • 您的解决方案也有效!感谢您的帮助@mrhn
  • 一般来说,如果答案对您有帮助或质量高,请在 stackoverflow 上投赞成票,不要靠我自己,还要看 HCK 的答案,这显然对您有所帮助。
  • 很好的接触,@mrhn +1。
  • 声望低于 15 人的投票将被记录,但不会更改公开显示的帖子得分。对不起各位
猜你喜欢
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 2020-04-22
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多