Reputation: 3
I have two tables, 'applications' and 'statuses' where there is a relation 'applications' BelongsTo 'statuses'. Lets begin with Model.
This is what ApplicationsTable looks like:
public function initialize(array $config)
{
$this->table('applications');
$this->displayField('title');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->hasOne('Statuses',
'foreignKey' => 'status_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Statuses', [
'foreignKey' => 'application_id',
'targetForeignKey' => 'status_id',
'joinTable' => 'applications_statuses'
]);
}
And StatusesTable looks like:
public function initialize(array $config)
{
$this->table('statuses');
$this->displayField('title');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('Applications', [
'className' => 'Applications',
'foreignKey' => 'status_id'
]);
}
This is what ApplicationsController for index looks like:
public function index()
{
$this->paginate = [
'contain' => 'Users', 'Statuses'
];
$this->set('applications', $this->paginate($this->Applications));
$this->set('_serialize', ['applications', 'statuses']);
}
I want to show the titles of the status instead the id's on index.ctp
And here index.ctp from Applications look like:
<?php foreach ($applications as $application): ?>
<tr>
<td>
<?= $application->has('user') ? $this->Html->link($application->user->name, ['controller' => 'Users', 'action' => 'view', $application->user->id]) : '' ?>
</td>
<td><?= $this->Html->link($application->title, ['action' => 'view', $application->id]) ?></td>
<td><?= h($application->companyname) ?></td>
<td><?= h($application->city) ?>, <?= h($application->country) ?></td>
<td><?= h($application->status_id) ?></td> // **I want to get the titles of the status instead the id.**
<td><?= h($application->modified) ?></td>
<td class="actions">
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $application->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $application->id], ['confirm' => __('Are you sure you want to delete # {0}?', $application->id)]) ?>
</td>
</tr>
But I got always as the output the id. I tried several ways:
1. <?= h($application->status_title) ?> // It doesn't work but it works for user
2. 'contain' => ['Users', 'Statuses'] // Change in ApplicationsController
<?= $application->has('status') ? $this->Html->link($application->status->title, ['controller' => 'Statuses', 'action' => 'view', $application->status->id]) : '' ?>
3. <td><?= h($application->status->title); ?></td>
Upvotes: 0
Views: 1044
Reputation: 4776
First make sure you models are configured.
// Remove this part from your model
$this->hasOne('Statuses',
'foreignKey' => 'status_id',
'joinType' => 'INNER'
]);
// Replace it with
$this->belongsTo('Statuses', [
'foreignKey' => 'status_id',
'joinType' => 'INNER'
]);
In view you should be able to load your data like this:
<td><?= h($application->status->title); ?></td>
The other would be an other solution:
In your controller if you want to retrieve $statuses separately rather than paginating the $statuses try to do find()
$this->set('statuses', statuses->find());
and then you can load the data in your view:
<td><?= $statuses[$application->status_id][title]; ?></td>
Upvotes: 0
Reputation: 60473
First of all your associations should use unique names, you cannot uses Statuses
for the belongsTo
as well as the belongsToMany
association (same goes for Applications
).
And then mind your syntax, the Statuses
string is not being passed to the contain
option, but is rather set as a value in the paginate
options array
'contain' => 'Users', 'Statuses' // < it's on the same level as `contain`
It should be
'contain' => ['Users', 'Statuses']
And then this
<?= $application->has('status') ? $this->Html->link($application->status->title, ['controller' => 'Statuses', 'action' => 'view', $application->status->id]) : '' ?>
should work fine for the belongsTo
association. The belongsToMany
of course would need to be treated differently, as the property would hold an array.
Upvotes: 1
Reputation: 7005
<?= h($application->status->title) ?>
PS: I would suggest putting a __toString()
on your Status object, which returns the title. Then you can just do
<?= h($application->status) ?>
If you have:
function __toString(){
return $this->title;
}
Upvotes: 0