Checking that relation between tables exists
@param string $local local table
@param string $foreign related table
@return bool relation exists
@throws LazerException
765591
public static function relation($local, $foreign)
    {
        $relations = Config::table($local)->relations();
        if (isset($relations->{$foreign}))
        {
            return TRUE;
        }

        throw new LazerException('Relation "' . $local . '" to "' . $foreign . '" doesn\'t exist');
    }
1337819
public function foreignMany($related, $foreignKey = null, $localKey = null)
    {
        $instance = new $related;

        $foreignKey = $foreignKey ?: Str::snake(class_basename($this)).'_id';

        $localKey = $localKey ?: '_id';

        return new ForeignMany($this, $instance->query(['*']), $foreignKey, $localKey);
    }
666628
public function leftJoin(
        $foreign_table,
        $master_field = null,
        $join_kind = null,
        $_foreign_alias = null,
        $relation = null
    ) {
        if (!$join_kind) {
            $join_kind = 'left';
        }
        $res = $this->join($foreign_table, $master_field, $join_kind, $_foreign_alias, $relation);
        $res->delete_behaviour = 'ignore';

        return $res;
    }
884383
public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
    {
        if (is_null($relation)) {
            $relation = $this->getBelongsToManyCaller();
        }

        $foreignKey = $foreignKey ?: $this->getForeignKey();

        $instance = new $related;

        $otherKey = $otherKey ?: $instance->getForeignKey();

        if (is_null($table)) {
            $table = $this->joiningTable($related);
        }

        $query = $instance->newQuery();

        return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation);
    }
564048
public function hasOne(Model $relatedModel, $foreignKey)
    {
        if ($relatedModel->isIgnored()) {
            return;
        }

        $this->relations->add(
            new Relations\HasOne($this, $relatedModel, $foreignKey)
        );
    }
150792
public function ini($related, $model, $intermediate = null, $local = null, $remote = null)
    {
        $relatedTable = $this->getTable($related);
        $modelTable = $this->getTable($model);
        //
        $intermediate = is_null($intermediate) ? $this->getIntermediate($modelTable, $relatedTable) : $intermediate;
        //
        $this->checkModels($related, $intermediate, get_class($model));
        //
        $localVal = $this->relationValue($related, $model, $local);
        $localColumn = $this->relationColumn($related, $model, $local);
        $remoteColumn = $this->remoteColumn($related, $remote);
        //
        return $mod = $this->relate($related, $intermediate, $remoteColumn, $localColumn, $localVal);
    }
612441
protected function getManyToManyRelationSelectSQL(RelationDescription $relationDescription,
          array $otherObjectProxies, $otherRole, $criteria=null, $orderby=null,
          PagingInfo $pagingInfo=null) {
    $thisRelationDesc = $relationDescription->getThisEndRelation();
    $otherRelationDesc = $relationDescription->getOtherEndRelation();
    $nmMapper = self::getMapper($thisRelationDesc->getOtherType());
    $otherFkAttr = $nmMapper->getAttribute($otherRelationDesc->getFkName());
    $nmTableName = $nmMapper->getRealTableName();

    // id parameters
    $parameters = [];
    $idPlaceholder = ':'.$nmTableName.'_'.$otherFkAttr->getName();
    for ($i=0, $count=sizeof($otherObjectProxies); $i<$count; $i++) {
      $dbid = $otherObjectProxies[$i]->getValue($otherRelationDesc->getIdName());
      if ($dbid === null) {
        $dbid = SQLConst::NULL();
      }
      $parameters[$idPlaceholder.$i] = $dbid;
    }

    // statement
    $queryId = $this->getCacheKey($otherRole.sizeof($otherObjectProxies), null, $criteria, $orderby, $pagingInfo);
    $selectStmt = SelectStatement::get($this, $queryId);
    if (!$selectStmt->isCached()) {
      // initialize the statement

      $thisFkAttr = $nmMapper->getAttribute($thisRelationDesc->getFkName());
      $thisIdAttr = $this->getAttribute($thisRelationDesc->getIdName());

      $tableName = $this->getRealTableName();
      $selectStmt->from($tableName, '');
      $this->addColumns($selectStmt, $tableName);
      $joinCond = $nmTableName.'.'.$thisFkAttr->getColumn().'='.$tableName.'.'.$thisIdAttr->getColumn();
      $joinColumns = [];
      $selectStmt->where($this->quoteIdentifier($nmTableName).'.'.
          $this->quoteIdentifier($otherFkAttr->getColumn()).' IN('.join(',', array_keys($parameters)).')');
      // order (in this case we use the order of the many to many objects)
      $nmSortDefs = $nmMapper->getDefaultOrder($otherRole);
      $hasNmOrder = sizeof($nmSortDefs) > 0;
      $orderType = $hasNmOrder ? $nmMapper->getType() : $this->getType();
      $orderTable = $hasNmOrder ? $nmTableName : $tableName;
      $defaultOrderDef = $hasNmOrder ? $nmSortDefs : $this->getDefaultOrder($otherRole);
      $this->addOrderBy($selectStmt, $orderby, $orderType, $orderTable, $defaultOrderDef);
      foreach($nmSortDefs as $nmSortDef) {
        // add the sort attribute from the many to many object
        $nmSortAttributeDesc = $nmMapper->getAttribute($nmSortDef['sortFieldName']);
        $joinColumns[$nmSortAttributeDesc->getName()] = $nmSortAttributeDesc->getColumn();
      }
      // add proxy id
      $joinColumns[self::INTERNAL_VALUE_PREFIX.'id'] = $otherFkAttr->getColumn();
      $selectStmt->join($nmTableName, $joinCond, $joinColumns);
      // additional conditions
      $parameters = array_merge($parameters, $this->addCriteria($selectStmt, $criteria, $nmTableName));
      // limit
      if ($pagingInfo != null) {
        $selectStmt->limit($pagingInfo->getPageSize());
      }
    }
    else {
      // on used statements only set parameters
      $parameters = array_merge($parameters, $this->getParameters($criteria, $nmTableName));
    }

    // set parameters
    $selectStmt->setParameters($parameters);

    // always update offset, since it's most likely not contained in the cache id
    if ($pagingInfo != null) {
      $selectStmt->offset($pagingInfo->getOffset());
    }
    return [$selectStmt, $otherRelationDesc->getIdName(), self::INTERNAL_VALUE_PREFIX.'id'];
  }
924149
public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
    {
        if (is_array($foreignKey)) { //Check for multi-columns relationship
            $this->validateRelatedModel($related);
        }

        // If no relation name was given, we will use this debug backtrace to extract
        // the calling method's name and use that as the relationship name as most
        // of the time this will be what we desire to use for the relationships.
        if (is_null($relation)) {
            $relation = $this->guessBelongsToRelation();
        }

        $instance = $this->newRelatedInstance($related);

        // If no foreign key was supplied, we can use a backtrace to guess the proper
        // foreign key name by using the name of the relationship function, which
        // when combined with an "_id" should conventionally match the columns.
        if (is_null($foreignKey)) {
            $foreignKey = Str::snake($relation).'_'.$instance->getKeyName();
        }

        // Once we have the foreign key names, we'll just create a new Eloquent query
        // for the related models and returns the relationship instance which will
        // actually be responsible for retrieving and hydrating every relations.
        $ownerKey = $ownerKey ?: $instance->getKeyName();

        return new BelongsTo($instance->newQuery(), $this, $foreignKey, $ownerKey, $relation);
    }
1224827
protected function hasOne(string $model, ?string $foreignKey = null): HasOne
	{
		$related = new $model;

		return new HasOne($related->getConnection(), $this, $related, $foreignKey);
	}
82910
public function hasMany($modelName, $foreignKey=null, $localKey=null)
    {
        return $this->_relationship($modelName, __FUNCTION__, $foreignKey, $localKey);
    }
688358
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
    {
        $this->output->createForeignKey($fkConstraint, $localTable);
    }
233201
protected function isHasOne($foreignKey)
    {
        $remote = $this->describes[$foreignKey->TABLE_NAME];
        foreach ($remote as $field) {
            if ($field->Key == 'PRI') {
                if ($field->Field == $foreignKey->COLUMN_NAME) {
                    return true;
                }
            }
        }

        return false;
    }
453225
public function setRelation()
    {
        if (!in_array(null, $this->tables) && !in_array(null, $this->keys))
        {
            $this->addRelation();
            return true;
        }
        else
        {
            throw new LazerException('Tables names or keys missing');
        }
    }
656454
public function filterJoinedRelation($related)
    {
        // Apply any relation based scope to avoid method duplication
        $this->callRelatedLocalSetup($related, $this->query);

        foreach ($this->getLocalRelation($related) as $closure) {
            // If a relation is defined locally in a method AND is joined
            // Then we call those defined relation closures on this query
            $closure($this->query);
        }

        // Check if we have input we need to pass through a related Model's filter
        // Then filter by that related model's filter
        if (count($relatedFilterInput = $this->getRelatedFilterInput($related)) > 0) {
            $filterClass = $this->getRelatedFilter($related);

            // Disable querying joined relations on filters of joined tables.
            (new $filterClass($this->query, $relatedFilterInput, false))->handle();
        }
    }
689427
protected function relate($remote, $intermediates, $remoteColumn, $localColumn, $localValue)
    {
        $intermediates = $this->intermediates($intermediates, $localColumn, $localValue);
        //
        if (!is_null($intermediates)) {
            return $this->all($intermediates, $remote, $remoteColumn);
        }
        //
    }
526218
public function hasReferrer(ForeignKey $fk)
    {
        return $this->hasReferrers() && in_array($fk, $this->referrers, true);
    }
307559
public function hasOne(string $related, string $primary_key = '', string $foreign_key = '')
    {
        $relatedModel = app()->make($related);
        $local_key = $local_key ?? $this->getKey();
        // Make the table name singular and append ID to it
        // FIXME: Use a more reliable approach
        $foreign_key = $foreign_key ?? rtrim($relatedModel->getTable(), 's').'_id';
        return new HasOne($relatedModel, $this, $primary_key, $foreign_key);
    }