Laravel - Really struggling to understand eloquent

故事扮演 提交于 2019-12-24 00:42:45

问题


I'm fairly new to Laravel having come over from Codeigniter and for the most part I really like it, but I really can't get my head around Eloquent.

If I want to do a simple query like this:

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

I try doing something like this (with a "belongs to"):

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

But now I have two queries and an IN() which isn't really needed, like so:

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

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

So I try and force a join like so:

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

And now I get an error like so:

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,
)

It's obvious where the error is, the where needs to use something like "site.id = ?". But I can't see anyway to make this happen?

So i'm just stuck going back to fluent and using:

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

I guess it's not a massive problem. I would just really like to understand eloquent. I can't help but feel that i'm getting it massively wrong and misunderstanding how it works. Am I missing something? Or does it really have to be used in a very specific way?

I guess my real question is: Is there anyway to make the query I want to make using Eloquent?


回答1:


I actually find this behaviour advantageous. Consider this (I'll modify your example). So we have many sites and each has many tweeters. Each site has a lot of info in the DB: many columns, some of them text columns with lots of text / data.

You do the query your way:

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

There are two downsides:

  1. You get lots of redundant data. Each row you get for a tweeter of the same site will have the same site data that you only need once so the communication between PHP and your DB takes longer.
  2. How do you do foreach (tweeter_of_this_site)? I'm guessing you display all the sites in some kind of list and then inside each site you display all of it's tweeters. You'll have to program some custom logic to do that.

Using the ORM approach solves both these issues: it only gets the site data once and it allows you to do this:

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

What I'm also saying is: don't fight it! I used to be the one that said: why would I ever use an ORM, I can code my own SQL, thank you. Now I'm using it in Laravel and it's great!




回答2:


You can always think of Eloquent as an extension of Fluent.

The problem you're running into is caused by the find() command. It uses id without a table name, which becomes ambiguous.

It's a documented issue: https://github.com/laravel/laravel/issues/1050

To create the command you are seeking, you can do this:

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

Of course, your syntax with join()->find() is correct once that issue fix is adopted.



来源:https://stackoverflow.com/questions/14130338/laravel-really-struggling-to-understand-eloquent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!