Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Better use of ORM?
  • Hi guys Look at the following code, I believe there must be a better way to use ORM to do what I'm trying to achieve but I can't seem to get my head around it. In my activity controller I have;
    <?php
    
    class Controller_Activity extends Controller_Application
    {
     public function action_index()
     {
      $friends = array();
      foreach ($this->current_user->friends as $f)
      {
       $friends[] = $f->friend_id;
      }
    
      $this->data['activities'] = Model_Activity::find()
              ->where('user_id', 'IN', $friends)
              ->order_by('created_at', 'desc')
              ->get();
      
      $this->template->title = 'Activity';
      $this->template->content = View::forge('activity/index', $this->data);
     }
    
    }
    

    Any suggestions to make it smaller?
  • I don't see an immediate improvement. If "friends" isn't eager loaded, this will fire a "SELECT *" on friends. In that case it would be better to do something like this:
    $friends = array(); 
    $result = Model_Friends::query()->select('friend_id')->where('user_id', '=', $this->current_user->id)->get();
    foreach ($result as $f)
    {
        $friends[] = $f->friend_id; 
    }
    
    which results in a slightly more optimal query.
  • The models are setup for users to have friends, and a friend to be a self referencing model to the users table as a friend. So without any additional queries normally I can do $user->friends and it'll give me the friends. Looks good though. I'll give it a blast :)
  • What I mean with eager loading is that when you ran the query to fetch $this->current_user, if you have included "->related('friends')" (or the same in array notation), a join is executed to fetch both the current_user and prepopulate the friends objects. If not, then the ORM will fire a "SELECT *" query as soon as you access a friends object, which means a second query. Only in this case a slight improvement is possible, because in terms of efficiency nothing beats retrieving the data using a join.
  • Harro Verton wrote on Wednesday 3rd of October 2012:
    What I mean with eager loading is that when you ran the query to fetch $this->current_user, if you have included "->related('friends')" (or the same in array notation), a join is executed to fetch both the current_user and prepopulate the friends objects. If not, then the ORM will fire a "SELECT *" query as soon as you access a friends object, which means a second query. Only in this case a slight improvement is possible, because in terms of efficiency nothing beats retrieving the data using a join.

    My query for current_user is the following
    $this->current_user = Model_User::find($user_id);
    
  • Ok, in that case you're "friends" are not pre-fetched, and accessing the property will fire a "SELECT * FROM friends WHERE user_id = x" query.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion