We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

[EAGER Loading] Avoid lazy loading by using the query builder.

Like a me, others want the ability the eagerly load models:

Because this is not implemented yet, I'm trying to write my own eager loader by using the query builder.

In the following code snippet my goal is to fetch all Users with their friends.

    $users = $app->modelsManager->createBuilder()
        ->from('User')
        ->join('User\UserRelationship', 'User\UserRelationship.user_id_2 = User\User.id')
        ->getQuery()->execute();

I've defined the relationship in the user class as the following:

        $this->hasMany("id", 'user\UserRelationship', "user_id_2", array(
            'alias' => 'Friends'
        ));

Now when I loop the users and fetch their friends it still lazy loads the relationship.

    foreach($users as $user){
        foreach($user->friends as $friend){
            print_r($friend->toArray());
        }
    }

What am I doing wrong?



98.9k

It doesn't work that way, you have to get both records:

$results = $app->modelsManager->createBuilder()
        ->columns('Robots.*', 'Parts.*')
        ->from('Robots')
        ->join('Parts', 'Robots.id = Parts.robotsId')
        ->getQuery()->execute();
foreach ($results as $row) {
    echo $row->robots->id, $row->parts->id, '<br>';
}

I should then instantiate the models myself?



3.0k

@boedy: have you found a way to instantiate the models from the result of the builder as the core team suggested?

I'm also looking for a solution to 'eager load' (not all but the) needed related entities (as we already met in forum topic: https://forum.phalcon.io/discussion/3482/model-hierarchy-avoiding-lazy-loading), but still not found a way to solve it.

What I (or we) would like to achieve is to have each Robot entities (and each one only once!) with all their associated RobotParts entities (pre)loaded in their RobotsParts model instance properties. Dear core team, is this possible somehow? We must avoid lazy loading each entity lists ($robot->RobotsParts) because that kills the DB.

I've stopped using the Phalcon orm and I've switch to the ORM laravel uses. https://github.com/illuminate/database



3.0k

I'm sorry to hear that... But I have to say I don't see a way out either, so I've also started to use another ORM (Doctrine by the way). I thinks Phalcon's ORM has a lot of missing features that are needed even for quite simple situations, I don't understand the core team why the don't listen to our requests that are so important. I know, they're busy with rewriting the version 2.0.0 and have lot of other tasks, but the eager loading feature has been reported for a year now (https://github.com/phalcon/cphalcon/issues/1117) and we haven't got not even a tiny feedback about it if/when they at least will consider implementing it.

Without such feautre, I think the ORM is not suitable for projects starting from a low-medium complexity, maybe only for very small projects with a very few database tables. Sorry to summarize my few week of researching with the ORM like this, because the framework itself looks great! Only the ORM... It's fast, faster than doctrine (at least its boot time, haven't tested further), but we cannot start a project with a feature-lacking ORM that doesn't get nor support, neither feedback about important features. I'm sad :(



98.9k

I think the problem is the conception of open source most people have: we ask something and the phalcon team must go and start writing it just because we want/need it.

This is an open source project, we're not a company, is you want something, you can start implementing it, Phalcon 2 is written in an easier and friendly language, if you don't have time for that, why blame us? No one has time for that now then.



3.0k

Sorry, you're right. I'm just sad about the fact that this (I think important) feature hasn't already been implemented in the ORM by the time (now) I started to research Phalcon's capability (and possibly will start at least on new project with it), while the core itself looks well featured (therefore there's difference in the ORM's and the core's usability, functionality I think). I don't blame anybody, I'm just sad that I have to learn a different ORM, while Phalcon's ORM looked primising as well (mostly its performance because of C extension).

Yeah I could participate in its implementation, but I don't think I would have enough time and mostly knowledge right now to overview the whole project, implement this feature and manage the migration to the core. I know, nobody else has... so nobody to blame, I'm just disappointed a bit because (kind of) this is the only mandatory feature which lack stops me using Phalcon's ORM... But sorry, nobody to blame, really, but a tiny feedback about this feature request in a year's time would have been appretiated, even if that's a NO from somebody in the core team who has decision about feature requests.

Phalcon you are right. Nobody to blame, of course. Anyway it would be really good to have such a improvement on the ORM. There is lot of use cases to wish for an eager loading, I know about doing a criteria/phql but it does development a pain (relationships, joins, etc...)

I would like to fetch a ton of models and it's multiple related models without quering the database a ton of times. also, think about the cache with this eager load, It will make really easy actual complicated stuff with phalcon.

I think the problem is the conception of open source most people have: we ask something and the phalcon team must go and start writing it just because we want/need it.

This is an open source project, we're not a company, is you want something, you can start implementing it, Phalcon 2 is written in an easier and friendly language, if you don't have time for that, why blame us? No one has time for that now then.



43.9k

Hi,

To be sure: is "eager loading" obtaining in one query, objects and their related records ? If so, does response above satisfy that need ? (I do think so)

The above does solve it, but I need to write logic, (join condition, models to fetch, execute query.... instead of relying on the Model abstraction when I define relationships. Also the "above" solution does return the join of each table? like a sql join? so, lot of repeated information I don't need.

I think that eager loading is a no-brain must-have functionality on any ORM ActiveRecord. But of course, I understand that nobody is having the necesary time or motivation to do it. I would like to try, but as many of you I don't have the time nor the willing to do it after work.

I did, some time ago an Active recor with a simple eager loading implementation: https://github.com/Surt/Granada#eager-loading

Hi,

To be sure: is "eager loading" obtaining in one query, objects and their related records ? If so, does response above satisfy that need ? (I do think so)



43.9k

Maybe it's possible for some skilly developer to write a pure php solution and push it into the incubator.