/**
  * Test clearing containments but not matching joins.
  *
  * @return void
  */
 public function testClearContain()
 {
     $contains = ['clients' => ['orders' => ['orderTypes', 'stuff' => ['stuffTypes']], 'companies' => ['categories']]];
     $loader = new EagerLoader();
     $loader->contain($contains);
     $loader->matching('clients.addresses');
     $this->assertNull($loader->clearContain());
     $result = $loader->normalized($this->table);
     $this->assertEquals([], $result);
     $this->assertArrayHasKey('clients', $loader->matching());
 }
示例#2
0
 /**
  * Sets the list of associations that should be eagerly loaded along with this
  * query. The list of associated tables passed must have been previously set as
  * associations using the Table API.
  *
  * ### Example:
  *
  * ```
  *  // Bring articles' author information
  *  $query->contain('Author');
  *
  *  // Also bring the category and tags associated to each article
  *  $query->contain(['Category', 'Tag']);
  * ```
  *
  * Associations can be arbitrarily nested using dot notation or nested arrays,
  * this allows this object to calculate joins or any additional queries that
  * must be executed to bring the required associated data.
  *
  * ### Example:
  *
  * ```
  *  // Eager load the product info, and for each product load other 2 associations
  *  $query->contain(['Product' => ['Manufacturer', 'Distributor']);
  *
  *  // Which is equivalent to calling
  *  $query->contain(['Products.Manufactures', 'Products.Distributors']);
  *
  *  // For an author query, load his region, state and country
  *  $query->contain('Regions.States.Countries');
  * ```
  *
  * It is possible to control the conditions and fields selected for each of the
  * contained associations:
  *
  * ### Example:
  *
  * ```
  *  $query->contain(['Tags' => function ($q) {
  *      return $q->where(['Tags.is_popular' => true]);
  *  }]);
  *
  *  $query->contain(['Products.Manufactures' => function ($q) {
  *      return $q->select(['name'])->where(['Manufactures.active' => true]);
  *  }]);
  * ```
  *
  * Each association might define special options when eager loaded, the allowed
  * options that can be set per association are:
  *
  * - foreignKey: Used to set a different field to match both tables, if set to false
  *   no join conditions will be generated automatically. `false` can only be used on
  *   joinable associations and cannot be used with hasMany or belongsToMany associations.
  * - fields: An array with the fields that should be fetched from the association
  * - queryBuilder: Equivalent to passing a callable instead of an options array
  *
  * ### Example:
  *
  * ```
  * // Set options for the hasMany articles that will be eagerly loaded for an author
  * $query->contain([
  *   'Articles' => [
  *     'fields' => ['title', 'author_id']
  *   ]
  * ]);
  * ```
  *
  * When containing associations, it is important to include foreign key columns.
  * Failing to do so will trigger exceptions.
  *
  * ```
  * // Use special join conditions for getting an Articles's belongsTo 'authors'
  * $query->contain([
  *   'Authors' => [
  *     'foreignKey' => false,
  *     'queryBuilder' => function ($q) {
  *       return $q->where(...); // Add full filtering conditions
  *     }
  *   ]
  * ]);
  * ```
  *
  * If called with no arguments, this function will return an array with
  * with the list of previously configured associations to be contained in the
  * result.
  *
  * If called with an empty first argument and $override is set to true, the
  * previous list will be emptied.
  *
  * @param array|string $associations list of table aliases to be queried
  * @param bool $override whether override previous list with the one passed
  * defaults to merging previous list with the new one.
  * @return array|$this
  */
 public function contain($associations = null, $override = false)
 {
     if ($override) {
         $this->_eagerLoader->clearContain();
     }
     $result = $this->eagerLoader()->contain($associations);
     if ($associations !== null || $override) {
         $this->_dirty();
     }
     if ($associations === null) {
         return $result;
     }
     return $this;
 }