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

Defining relationships in namespaced models

This took me a while to figure out, so I want to post it here for future searches.

In the documentation, the examples all use non-namespaced models, like "Robots" and "Parts". Most people (I think) will actually be using namespaced models, such as "Myapp\Models\Robots" and "Myapp\Models\Parts". For namespaced models like this, you have to provide the full namespaced name of the model when providing the relationship definition.

Then, and here's the most important part, perhaps: you define an alias so you don't have to type the full path every time you use the relationship.

Here's an example out of my app, in which I wrote a little documentation for myself so I'd remember how it has to work. In this example, I have defining a User model that has a n-n relationship with a Role modle, through a junction table called User_Role.

namespace Siecomp\Models;

use Phalcon\Mvc\Model\Validator\Uniqueness;
use Phalcon\DI;

class User extends SiecompModel
{

  // ... properties ...

  public function initialize()
  {
    $this->setSource('user');

    // Roles relationship - n-n.

    /**
     * Signature of Phalcon's n-n definition so I don't have to look it up
     * every time...
     *
     * @param string Name of the id property of this model
     * @param string Full namespaced name of junction model
     * @param string Name of the id property of this model in the junction model
     * @param string Name of the id property of referenced model in the junction model
     * @param string Full namespaced name of the related model
     * @param string Name of the id property of the related model
     * @param array Options; most important is 'alias', which will be the name
     *                     of this relationship in getRelated methods.
     *                     Examples:
     *                     without alias: $user->getRelated('Siecomp\Models\Role')
     *                     with alias (explicit): $user->getRelated('Roles')
     *                     with alias (magic): $user->getRoles()
     *
     */
    $this->hasManyToMany(
      'id',
      'Siecomp\Models\Role_User',
      'user_id',
      'role_id',
      'Siecomp\Models\Role',
      'id',
      array(
        'alias' => 'Roles'
      )
    );

    // Invites relationship - 1-n; any given user can create many invites
    $this->hasMany('id', 'Siecomp\Models\Invite', 'creator_user_id');
  }

  // ... more methods ...

}


33.8k

Yeah, you need to use alias if you don't want to wrote everytime that long string. You're accesing a class, so you've to tell exactly his name (and his namespace if it has one).

BTW, you can also define the models relationship this way (personally, I prefer to get a class (and his namespace) name this way than hardcoding it):

use Siecop/Models/Invite;

/*
 * 'Class::class' will return the name class.
 * 'My/Namespace/Class::class' will return the name class along with his namespace.
 *
 * If you include the namespace above as this example, do the first way.
 */
$this->hasMany('id', Invite::class, 'creator_user_id');

True, that's a good trick! Especially if you might be changing the namespace later - you'll be covered. If anyone is writing code that may need to run on an older box, remember that the class constant mentioned above is only available in PHP 5.5+.