Cake\ORM\Association\BelongsToMany::attachTo PHP Method

attachTo() public method

The options array accept the following keys: - includeFields: Whether to include target model fields in the result or not - foreignKey: The name of the field to use as foreign key, if false none will be used - conditions: array with a list of conditions to filter the join with - fields: a list of fields in the target table to include in the result - type: The type of join to be used (e.g. INNER)
public attachTo ( Query $query, array $options = [] ) : void
$query Cake\ORM\Query the query to be altered to include the target table data
$options array Any extra options or overrides to be taken in account
return void
    public function attachTo(Query $query, array $options = [])
    {
        if (!empty($options['negateMatch'])) {
            $this->_appendNotMatching($query, $options);
            return;
        }
        $junction = $this->junction();
        $belongsTo = $junction->association($this->source()->alias());
        $cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->foreignKey()]);
        $cond += $this->junctionConditions();
        if (isset($options['includeFields'])) {
            $includeFields = $options['includeFields'];
        }
        // Attach the junction table as well we need it to populate _joinData.
        $assoc = $this->_targetTable->association($junction->alias());
        $newOptions = array_intersect_key($options, ['joinType' => 1, 'fields' => 1]);
        $newOptions += ['conditions' => $cond, 'includeFields' => $includeFields, 'foreignKey' => false];
        $assoc->attachTo($query, $newOptions);
        $query->eagerLoader()->addToJoinsMap($junction->alias(), $assoc, true);
        parent::attachTo($query, $options);
        $foreignKey = $this->targetForeignKey();
        $thisJoin = $query->clause('join')[$this->name()];
        $thisJoin['conditions']->add($assoc->_joinCondition(['foreignKey' => $foreignKey]));
    }

Usage Example

コード例 #1
0
 /**
  * Tests that attaching an association to a query will trigger beforeFind
  * for the target table
  *
  * @return void
  */
 public function testAttachToBeforeFindExtraOptions()
 {
     $query = $this->getMock('\\Cake\\ORM\\Query', ['join', 'select'], [null, null]);
     $config = ['sourceTable' => $this->article, 'targetTable' => $this->tag];
     $table = TableRegistry::get('ArticlesTags');
     $association = new BelongsToMany('Tags', $config);
     $listener = $this->getMock('stdClass', ['__invoke']);
     $this->tag->getEventManager()->attach($listener, 'Model.beforeFind');
     $opts = ['something' => 'more'];
     $listener->expects($this->once())->method('__invoke')->with($this->isInstanceOf('\\Cake\\Event\\Event'), $this->isInstanceOf('\\Cake\\ORM\\Query'), $opts, false);
     $listener2 = $this->getMock('stdClass', ['__invoke']);
     $table->getEventManager()->attach($listener2, 'Model.beforeFind');
     $listener2->expects($this->once())->method('__invoke')->with($this->isInstanceOf('\\Cake\\Event\\Event'), $this->isInstanceOf('\\Cake\\ORM\\Query'), [], false);
     $association->attachTo($query, ['queryBuilder' => function ($q) {
         return $q->applyOptions(['something' => 'more']);
     }]);
 }