I have a table with a belongsTo relationship, where I want to use an actual alias, not just the same name as the className. In buildRules() I refer to that alias, however, during a save() there are SQL errors that say the tabelized alias name is not a table. Here is the class below:
class SolarBuyerTiersPostsTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('solar_buyer_tiers_posts');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Posts', [
'foreignKey' => 'post_id',
'joinType' => 'INNER',
'className' => 'SolarPosts'
]);
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['buyer_tier_id'], 'BuyerTiers'));
$rules->add($rules->existsIn(['post_id'], 'Posts'));
return $rules;
}
}
The SQL error during a save() is
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'pingtree.posts' doesn't exist
I know posts doesn’t exist, but solar_posts does, and that’s the className in the association.
The workaround seems to be setting checkRules to false in the save options, or to create a duplicate belongsTo() with the alias as the same name as the className, and then use SolarPosts in the existsIn() call.
I did some debugging, and it seems like the target() method in Association uses the _name instead of the _className. Shouldn’t it use _className?
public function target(Table $table = null)
{
if ($table === null && $this->_targetTable) {
return $this->_targetTable;
}
if ($table !== null) {
return $this->_targetTable = $table;
}
if (strpos($this->_className, '.')) {
list($plugin) = pluginSplit($this->_className, true);
$registryAlias = $plugin . $this->_name;
} else {
$registryAlias = $this->_name;
}
$tableLocator = $this->tableLocator();
$config = [];
if (!$tableLocator->exists($registryAlias)) {
$config = ['className' => $this->_className];
}
$this->_targetTable = $tableLocator->get($registryAlias, $config);
return $this->_targetTable;
}