2

我是从 Codeigniter 过来的 Laravel 的新手,在大多数情况下我真的很喜欢它,但我真的无法理解 Eloquent。

如果我想做一个这样的简单查询:

SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id

我尝试做这样的事情(带有“属于”):

$site = Site::with('tweeter')->find($site_id);

但是现在我有两个查询和一个并不真正需要的 IN() ,如下所示:

SELECT * FROM `site` WHERE `id` = '12' LIMIT 1

SELECT * FROM `tweeter` WHERE `id` IN ('3')

所以我尝试像这样强制加入:

$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->find($site_id);

现在我得到一个像这样的错误:

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous

SQL: SELECT * FROM `site` INNER JOIN `tweeter` ON `tweeter`.`id` = `site.tweeter_id` WHERE `id` = ? LIMIT 1

Bindings: array (
  0 => 12,
)

很明显错误在哪里,哪里需要使用“site.id =?”之类的东西。但是我无论如何都看不到要发生这种情况?

所以我只是坚持回到流利的状态并使用:

DB::table('site')->join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id','=',$site_id)->first()

我想这不是一个大问题。我真的很想理解雄辩。我不禁觉得我弄错了,误解了它的工作原理。我错过了什么吗?还是真的必须以非常特定的方式使用它?

我想我真正的问题是:无论如何,我想使用 Eloquent 进行查询吗?

4

2 回答 2

3

我实际上发现这种行为是有利的。考虑一下(我将修改您的示例)。所以我们有很多站点,每个站点都有很多高音扬声器。每个站点在数据库中都有很多信息:很多列,其中一些包含大量文本/数据的文本列。

您按照自己的方式进行查询:

SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id

有两个缺点:

  1. 你会得到很多冗余数据。您为同一站点的高音扬声器获得的每一行都将具有您只需要一次的相同站点数据,因此 PHP 和您的数据库之间的通信需要更长的时间。
  2. 你如何做foreach(tweeter_of_this_site)?我猜你会在某种列表中显示所有站点,然后在每个站点中显示所有的高音扬声器。您必须编写一些自定义逻辑才能做到这一点。

使用 ORM 方法解决了这两个问题:它只获取站点数据一次,并且允许您这样做:

foreach ($sites as $site) {
    foreach($site->tweeters as $tweeter) {}
}

我还要说的是:不要打它!我曾经说过:我为什么要使用 ORM,我可以编写自己的 SQL,谢谢。现在我在 Laravel 中使用它,它很棒!

于 2013-01-03T11:26:02.707 回答
0

您总是可以将 Eloquent 视为 Fluent 的扩展。

您遇到的问题是由 find() 命令引起的。它使用id没有表名,这变得模棱两可。

这是一个记录在案的问题: https ://github.com/laravel/laravel/issues/1050

要创建您正在寻找的命令,您可以这样做:

$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id', '=', $site_id)->first($fields);

当然,一旦采用了问题修复程序,您的 join()->find() 语法就是正确的。

于 2013-01-02T22:45:12.717 回答