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

Model relation on multiple fields doesn't work

I want to create a Model relation on multiple fields, like this:

$this->hasOne(
    ['sSource', 'id'],
    'MediaLink,
    ['sModel', 'iModelId'],
    ['alias' => 'medialink']
);

This give me no results when I call the relation with ->getMediaLink(); The relation is working when I use a single column. Is this a bug, a not implemented function or is the relation not properly defined?

I'm using Phalcon 2.0.8.

edited Nov '15

Show use your current model class and MediaLink class. Just properties and relation is enough.

Also how is supposed to work ? Cuz i dont really see any point of this relation, cuz its not gonna be really relation in mysql for example, cuz there can be only one key not two.

Whats the point of this relation ?



1.0k
edited Nov '15

This are the two classes: User and MediaLink and the usage:

class User extends Core
{
    public $iOriginId;
    public $dtCreated;
    public $dtUpdated;
    public $dtLastLogin;
    public $dtLogin;
    public $iStatus;
    public $sEmail;
    public $sPassword;
    public $sFirstName;
    public $sPrefix;
    public $sLastName;
    public $sUserName;
    public $iBadLoginCount;
    public $dtLocked;
    public $sPasswordReset;
    public $bMenuState;
    public $sTokenKey;
    public $sToken;
    public $sSource;

    public function initialize() {

        parent::initialize();

        $this->modelsManager->addHasOne(
            $this,
            ['sSource', 'id'],
            '\Cms\Media\Models\Inzite\MediaLink',
            ['sModel', 'iModelId'],
            ['alias' => 'medialink']
        );

    }

}

class MediaLink extends Core {

    public $dtCreated;
    public $dtUpdated;
    public $iMediaId;
    public $sModel;
    public $iModelId;
    public $iWidth;
    public $iHeight;
    public $iCropX;
    public $iCropWidth;
    public $iCropY;
    public $iCropHeight;
    public $iScale;
    public $sSource;

    public function initialize() {
        parent::initialize();

        $this->modelsManager->addHasOne(
            $this,
            'iMediaId',
            __NAMESPACE__ . '\Media',
            'id',
            ['alias' => 'model']
        );

        $this->modelsManager->addHasOne(
            $this,
            ['sModel', 'iModelId'],
            '\Cms\User\Models\Inzite\User',
            ['sSource', 'id'],
            ['alias' => 'user']
        );

    }
}

Usage:

$oUser = User::findFirst(1);
$oUser->getMediaLink();

That has no results. Phalcon is creating a query with this WHERE stament:

WHERE `medialink`.`sModel` = NULL AND `medialink`.`iModelId` = NULL LIMIT 1

When I define the relation as below, it works fine, but then the result is not specific enough.

 $this->modelsManager->addHasOne(
    $this,
    'sSource',
    '\Cms\Media\Models\Inzite\MediaLink',
    'sModel',
    ['alias' => 'medialink']
);

or

 $this->modelsManager->addHasOne(
    $this,
    'id',
    '\Cms\Media\Models\Inzite\MediaLink',
    'iModelId',
    ['alias' => 'medialink']
);
edited Nov '15

What you mean by not specific enough ? Also you can use just hasOne instead of calling modelsManager :D

Maybe try to specify conditions and bind in the last paremeter of relation(in join)? Maybe it would work this way ?

But i still dont see anypoint of this relation. Well you have request = NULL. So maybe in your User there are just nulls for those values ?

https://docs.phalcon.io/en/latest/reference/models.html#defining-relationships

Revert to your first implementation, and call the magic property medialink (name defined with alias) instead of the method getMediaLink()



1.0k

I will explain what I want to do. There is a model called User. This model represents a MySQL table user with data of CMS users: loginname, password, etc. There is a model called BlockContent. This model represents a MySQL table blockcontent with website content such as text and images. There is a model called Media. This model represents a MySQL table media with information about uploaded files: file size, extension, etc. There is a model called MediaLink. This model represents a MySQL table medialink to link an uploaded file to a model like User or BlockContent.

One file can be linked to multiple models, that’s why there is a table MediaLink between Media and User or BlockContent.

MediaLink has three important columns. iMediaId (refers to Media->id), sModel (modelname: user or blockcontent) and iModelId (id from the User or BlockContent record).

An example:

iMediaId - sModel - iModelId
--------------------------------------
1 - user - 1
2 - user - 2
3 - blockcontent - 1
4 - blockcontent - 2

What I want to with the following lines is to get the upload (profile picture) of a user.

$user = User::findFirst('id = 1');
$user->getMediaLink();

Or get the uploade file to a blockcontent

$block = BlockContent::findFirst('id = 1');
$block->getMediaLink();

The column iModelId is not so I also have to select on the sModel. The combination sModel and iModelId is unique. That is why I want to create a model relation on two columns, like this example:

$this->modelsManager->addHasOne(
    $this,
    ['sModel', 'iModelId'],
    '\Cms\User\Models\Inzite\User',
    ['sSource', 'id'],
    ['alias' => 'user']
);