title: CakePHP 3.x DB mapping, BelongsToMany vs HasMany+HasOne
body: <p>I have three tables in DB: (1) <em>offers</em>, (2) <em>offer_rows</em>, (3) <em>products</em>.</p>
  
  <p><em>offer_rows</em> will always point to a <em>offer</em>, and possibly (but not always) to a <em>product</em>. <em>offer_rows</em> has also other fields such as price etc.</p>
  
  <p>Same with (My)SQL:</p>
  
  <pre><code>create table offers(
      id serial not null auto_increment primary key,
      ...
  );
  create table offer_rows(
      id serial not null auto_increment primary key,
  
      product_id bigint(20) unsigned references products(id),
      offer_id bigint(20) unsigned not null references offers(id),
  
      price decimal(15,2),
      ...
  );
  create table products(
      id serial not null auto_increment primary key,
      ...
  );
  </code></pre>
  
  <p>In terms of CakePHP (3.3.16), <strong>with the optional reference to a product</strong>, what is the correct mapping?</p>
  
  <p>If the <em>offer_rows</em> had a not null restriction to product reference (which it currently does not have), it would seem that a <strong>BelongsToMany</strong> should be used:</p>
  
  <pre><code>(class OffersTable)
  @property \Cake\ORM\Association\BelongsToMany $Products
  
  // initialize
  $this-&gt;belongsToMany('Products', [
       'through' =&gt; 'OfferRows',
       'foreignKey' =&gt; 'offer_id',
       'joinType' =&gt; 'INNER',
       'joinTable' =&gt; 'offer_rows',
  ]);
  
  
  (class OfferRowsTable)
  @property \Cake\ORM\Association\BelongsTo $Products
  @property \Cake\ORM\Association\BelongsTo $Offers
  
  // initialize
  $this-&gt;belongsTo('Products', [
       'foreignKey' =&gt; 'product_id'
  ]);
  $this-&gt;belongsTo('Offers', [
       'foreignKey' =&gt; 'offer_id',
       'joinType' =&gt; 'INNER'
  ]);
  
  
  (class ProductsTable)
  @property \Cake\ORM\Association\BelongsToMany $Offers
  
  // initialize
  $this-&gt;belongsToMany('Offers', [
       'through' =&gt; 'OfferRows',
       'foreignKey' =&gt; 'product_id',
       'joinType' =&gt; 'INNER',
       'joinTable' =&gt; 'offer_rows',
  ]);
  </code></pre>
  
  <p>However, with the possibility of the null product, should I use HasMany + HasOne instead?</p>
  
  <pre><code>(class OffersTable)
  @property \Cake\ORM\Association\HasMany $OfferRows
  
  // initialize
  $this-&gt;hasMany('OfferRows', [
      'foreignKey' =&gt; 'offer_id'
  ]);
  
  (class OfferRowsTable)
  @property \Cake\ORM\Association\BelongsTo $Offers
  @property \Cake\ORM\Association\HasOne $Products
  
  // initialize
  $this-&gt;belongsTo('Offers', [
         'foreignKey' =&gt; 'offer_id',
         'joinType' =&gt; 'INNER'
  ]);        
  $this-&gt;hasOne('Products', [
      'className' =&gt; 'Products',
          'propertyName' =&gt; 'reference_product_obj',
          'foreignKey' =&gt; 'reference_product'             
  ]);
  
  (class ProductsTable)
  @property \Cake\ORM\Association\BelongsToMany $OfferRows
  
  // initialize
  $this-&gt;belongsToMany('OfferRows', [
      'foreignKey' =&gt; 'product_id',
      'joinType' =&gt; 'INNER',
  ]);
  </code></pre>
  
  <p>Is either one correct, or is there third alternative?</p>