/**
  * built for hasMany relationships
  * in cases where the related record itself refers to a parent record,
  * write a custom query to load the related record including it's parent
  *
  * depends on the existance of a primaryKeyValue
  *
  * @param Relation|PhalconRelation $relation
  * @return array
  */
 protected function getHasManyRecords(Relation $relation)
 {
     $query = $this->buildRelationQuery($relation);
     $config = $this->getDI()->get('config');
     if (!array_deep_key($config, 'feature_flags.fastHasMany')) {
         // feature flag is disabled, only looking for one parent record
         // determine the key to search against
         $field = $relation->getFields();
         if (isset($this->baseRecord[$field])) {
             $fieldValue = $this->baseRecord[$field];
         } else {
             // fall back to using the primaryKeyValue
             $fieldValue = $this->primaryKeyValue;
         }
         $fieldName = $relation->getReferencedModel() . '.' . $relation->getReferencedFields();
         $query->where("{$fieldName} = \"{$fieldValue}\"");
     } else {
         // feature flag is enabled, pulling from register instead
         $foreign_keys = array_unique($this->hasManyRegistry[$relation->getReferencedModel()]);
         //name space the referenced field otherwise you might get ambigious errors
         $query->inWhere($relation->getReferencedModel() . '.' . $relation->getReferencedFields(), $foreign_keys);
     }
     $result = $query->getQuery()->execute();
     return $this->loadRelationRecords($result, $relation);
 }
 /**
  * help $this->queryBuilder to construct a PHQL object
  * apply join conditions and return query object
  *
  *
  * @param BuilderInterface $query
  * @return BuilderInterface
  */
 public function queryJoinHelper(BuilderInterface $query)
 {
     $config = $this->getDI()->get('config');
     $modelNameSpace = $config['namespaces']['models'];
     $columns = [];
     // join all active hasOne and belongTo instead of just the parent hasOne
     foreach ($this->entity->activeRelations as $relation) {
         // be sure to skip any relationships that are marked for custom processing
         $relationOptions = $relation->getOptions();
         if (isset($relationOptions) && (array_key_exists('customProcessing', $relationOptions) && $relationOptions['customProcessing'] === true)) {
             continue;
         }
         // refer to alias or model path to prefix each relationship
         // prefer alias over model path in case of collisions
         $alias = $relation->getAlias();
         $referencedModel = $relation->getReferencedModel();
         if (!$alias) {
             $alias = $referencedModel;
         }
         // structure to always join in belongsTo just in case the query filters by a related field
         $type = $relation->getType();
         switch ($type) {
             case Relation::BELONGS_TO:
                 // process feature flag for belongsTo
                 // attempt to join "simple" in side loaded belongsTo records that do not themselves have parents
                 if (array_deep_key($config, 'feature_flags.fastBelongsTo')) {
                     // create both sides of the join
                     $left = "[{$alias}]." . $relation->getReferencedFields();
                     $right = $modelNameSpace . $this->model->getModelName() . '.' . $relation->getFields();
                     // create and alias join
                     $query->leftJoin($referencedModel, "{$left} = {$right}", $alias);
                     $columns[] = "[{$alias}].*";
                 }
                 break;
             case Relation::HAS_ONE:
                 // create both sides of the join
                 $left = "[{$alias}]." . $relation->getReferencedFields();
                 $right = $modelNameSpace . $this->model->getModelName() . '.' . $relation->getFields();
                 // create and alias join
                 $query->leftJoin($referencedModel, "{$left} = {$right}", $alias);
                 // add all parent AND hasOne joins to the column list
                 $columns[] = "[{$alias}].*";
                 break;
                 // stop processing these types of joins with the main query.  They might return "n" number of related records
                 //                case Relation::HAS_MANY_THROUGH:
                 //                    $alias2 = $alias . '_intermediate';
                 //                    $left1 = $modelNameSpace . $this->model->getModelName() . '.' . $relation->getFields();
                 //                    $right1 = "[$alias2]." . $relation->getIntermediateFields();
                 //                    $query->leftJoin($relation->getIntermediateModel(), "$left1 = $right1", $alias2);
                 //
                 //                    $left2 = "[$alias2]." . $relation->getIntermediateReferencedFields();
                 //                    $right2 = "[$alias]." . $relation->getReferencedFields();
                 //                    $query->leftJoin($referencedModel, "$left2 = $right2", $alias);
                 //                    break;
             // stop processing these types of joins with the main query.  They might return "n" number of related records
             //                case Relation::HAS_MANY_THROUGH:
             //                    $alias2 = $alias . '_intermediate';
             //                    $left1 = $modelNameSpace . $this->model->getModelName() . '.' . $relation->getFields();
             //                    $right1 = "[$alias2]." . $relation->getIntermediateFields();
             //                    $query->leftJoin($relation->getIntermediateModel(), "$left1 = $right1", $alias2);
             //
             //                    $left2 = "[$alias2]." . $relation->getIntermediateReferencedFields();
             //                    $right2 = "[$alias]." . $relation->getReferencedFields();
             //                    $query->leftJoin($referencedModel, "$left2 = $right2", $alias);
             //                    break;
             default:
                 $this->di->get('logger')->warning("Relationship was ignored during join: {$this->model->getModelName()}.{$alias}, type #{$type}");
         }
     }
     $query->columns($columns);
     return $query;
 }