Laravel - 真的很难理解雄辩

时间:2013-01-02 22:34:59

标签: laravel eloquent

我对来自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制作我想要的查询?

2 个答案:

答案 0 :(得分:3)

我实际上发现这种行为是有利的。考虑一下(我会修改你的例子)。所以我们有很多网站,每个网站都有很多推文。每个站点在数据库中都有很多信息:很多列,其中一些是带有大量文本/数据的文本列。

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

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

有两个缺点:

  1. 您获得了大量冗余数据。您为同一站点的高音扬声器获得的每一行都将具有您只需要一次的相同站点数据,因此PHP与您的数据库之间的通信需要更长的时间。
  2. 你如何做foreach(tweeter_of_this_site)?我猜你在某种列表中显示所有网站,然后在每个网站内显示所有它的推文。你必须编写一些自定义逻辑才能做到这一点。
  3. 使用ORM方法可以解决这两个问题:它只获取一次站点数据并允许您执行此操作:

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

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

答案 1 :(得分: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()的语法是正确的