Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

An object relationship with different objects in model

Hello, I have a question and want to know the best way to solve it.

I have 3 models:

  CREATE TABLE IF NOT EXISTS `homes` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `modifiedAt` timestamp NULL DEFAULT NULL,
 `type` varchar(50) NOT NULL COMMENT 'Casa mata, piso, chalet, adosado, duplex, etc..',
 `alias` varchar(50) DEFAULT NULL,
 `rental` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Si está para alquilar o no',
 `description` text,
 `terrace` int(11) DEFAULT NULL COMMENT 'metros de terraza',
 `parking` int(11) DEFAULT NULL COMMENT 'nº parkings',
 `storage` tinyint(1) DEFAULT NULL,
 `garden` tinyint(1) DEFAULT NULL,
 `restroom` smallint(6) DEFAULT NULL,
 `bedsrooms` smallint(6) DEFAULT NULL,
 `size` smallint(6) DEFAULT NULL COMMENT 'metros totales',
 `energy_rating` varchar(1) DEFAULT NULL,
 `floors` smallint(3) DEFAULT NULL,
 `active` tinyint(1) DEFAULT '1',
 `communityId` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `id` (`id`),
 KEY `communityId` (`communityId`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;

CREATE TABLE IF NOT EXISTS `incidences` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modifiedAt` timestamp NULL DEFAULT NULL,
  `for` varchar(50) NOT NULL,
  `forId` int(11) NOT NULL,
  `userId` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `description` text,
  `date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `state` smallint(6) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `userId` (`userId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=32 ;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `surname` varchar(100) DEFAULT NULL,
  `email` varchar(255) NOT NULL,
  `password` char(60) NOT NULL,
  `mustChangePassword` char(1) DEFAULT NULL,
  `profilesId` int(10) unsigned NOT NULL,
  `banned` char(1) NOT NULL,
  `suspended` char(1) NOT NULL,
  `active` char(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `profilesId` (`profilesId`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=29 ;

In my models to link users with incidents (the owner)

$this->hasMany('id',
        __NAMESPACE__ . '\Incidences',
        'userId',
        array(
            'alias' => 'incidences',
    ));

An incident can be a home or other object. So I have two fields to identify who it is, "for" the object regards the incidence and "FORID" id.

How I can make the relationship between home and incidence in the model? Is there any way? Something like this?

$this->belongsTo(array('id',''),
        'Incidences',
        array('id','Homes'),
        array(
            'alias' => 'incidences')
    );

I solved it by a specific function for this, but I wonder if there is another "smarter" way.

class Homes extends Model {
...
  public static function getIncidences($id){
      return parent::find(array(
          "[for] = ?0 and [forId] = ?1",
          'bind' => array(
              0 => 'Homes',
              1 => $id
          )
      ));
  }
 ... 
 }

Thanks :)



107.3k
Accepted
answer
edited Apr '16

From some phalcon version there is ability to pass params to options in relation, it's just the same parameters which are in for example:

Homes::find($params)

So you could possibly do something like this:

$this->belongsTo('incidences',
        'Incidences',
        'id',
        array(
            'alias' => 'incidences',
            'params' => [
                'conditions'=>'for = Homes AND forId = :id:',
                'bind' => [
                    'id'=>$this->id
                ]
            ]
        )
    );

But i think it's not gonna work in intialize method beacause of $this->id will be just null. I guess it would maybe work if you put it under onConstruct(not sure) and definitely should work in afterFetch method.

Also remember this relation will only work on full objects.



1.8k

Thanks :)