laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.7k stars 11.06k forks source link

Eloquent, why two queries? #211

Closed liweihan closed 11 years ago

liweihan commented 11 years ago

Hi, when Eloquent handles a one2one relation table say the User and Phone table example in documentation $phone = User::find(1)->phone;

this will execute two queries select * from users where id = 1 select * from phones where user_id = 1

but the purpose of User::find(1)->phone is just to get a phone number why we need the first query then? thanks

alexwhitman commented 11 years ago

http://four.laravel.com/docs/eloquent#eager-loading

kapv89 commented 11 years ago

because of the relation. How the statement User::find(1)->phone is parsed is something like this

$user = User::find(1); $user->phone goes through the Eloquent::__get to Eloquent::getAttribute , where its identified as a relation and the key 'phone' is set in the user objects $relations property, and the object phone is returned.

If you want the model to always load up the details from phone table, you can override the newQuery method in User class to always join the phone table no matter what.

liweihan commented 11 years ago

I got your idea, it's logically correct. but still, the first query is not necessary. In this case I have the user_id already, why don't I just get the row from Phone? doesn't user_id in Phone point to id in User? any encoding of these two?

franzliedke commented 11 years ago

You can do that, too:

Phone::where_user_id(1)->get();
liweihan commented 11 years ago

My understanding, so far, is that there is always a query on the table of the static Model( here is User)to make the Model a concrete , even I just want to take a data from a related table, it's same for eager loading. if it's true, then it must be a weakness of using ORM

robclancy commented 11 years ago

You could do new User(['id' => 1])->phone

taylorotwell commented 11 years ago

Phone::where('user_id', 1)->first().

liweihan commented 11 years ago

it could be a way to avoid double queries, thank you guys

robclancy commented 11 years ago

I wasn't showing you how you should do it, just how you can make a similar User object without executing a query.