我有两张桌子,门票和绘画。一张票可以有许多画作,许多票可以使用一幅画。他们有一个名为 tickets_paintings 的连接表,其中包含 ticket_id 和 painting_id 。这是表格的设置方式:
class TicketsTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Paintings', [
'foreignKey' => 'ticket_id',
'targetForeignKey' => 'painting_id',
'joinTable' => 'tickets_paintings'
]);
}
class PaintingsTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Tickets', [
'foreignKey' => 'painting_id',
'targetForeignKey' => 'ticket_id',
'joinTable' => 'tickets_paintings'
]);
}
每张票都有一个字段"活跃"这是布尔值,告诉我票证当前是否正在使用中。在编辑功能中,该字段可以更改为true或false。
但现在我还需要每幅画的属性,告诉我这幅画目前是否用在活动票上。在这种情况下,它将无法在另一张票上使用。
我以为我可以为绘画添加布尔虚拟属性,检查它是否(当前)与任何具有active =>的故障单相关联。为true,因此也设置为true或false。 赞:"此绘画是否属于状态有效的票证=> 0&#34 ;. 然后相应地设置虚拟属性,以便我可以在视图中显示它。
我设法为绘画创建一个虚拟属性,检查到目前为止在连接表中是否有其ID的条目:
class Painting extends Entity
{
protected function _getIsAvailable(){
$TicketsTable = TableRegistry::get('TicketsPaintings');
$exists = $TicketsTable->exists(['painting_id' => $this->id]);
if($exists == true){
return 1;
} else {
return 0;
}
}
}
A)我如何添加一个条件来检查连接表中是否有匹配的ticket_id有一个active =>原始门票表中的1个?
查询必须以DESC顺序检查连接表中的ticket_id,并在找到第一个活动故障单后立即返回true(因此每次都不检查整个事件)
我甚至不了解如何访问"活跃"票据表上的属性进行检查。我想我必须使用"有很多通过"选项?!但是,即使尝试按照书中的解释和this question 完全(几个小时),我也无法让这个用于我的例子,因为我不明白正确的语法,我必须用于我的表。
B)是否可行或是否可取的"在实体内检查这样的事情吗?
我首先尝试在绘画表中使用额外的数据库字段,但每次编辑故障单时检查并设置另一个值似乎要复杂得多(不是我设法使其工作)...和票价和绘画的活跃价值几乎翻了一番。所以我认为虚拟财产更容易处理。还是我在完全错误的火车上?
感谢您对此噩梦的任何提示或建议=)!
答案 0 :(得分:1)
由于没有人来救我,我设法把东西放在一起,实际上创造了我想要的虚拟财产。我不知道这是不是最好的方法,但它适用于我,我会把它放在这里以防万一有人在寻找类似的情况。
我在绘画表中创建了一个finder方法,它连接3个表并过滤掉连接到活动票证的所有绘画。
class PaintingsTable extends Table
{
public function findNotavailable(Query $query, array $options){
$query
->join([
'tickets_paintings' =>[
'table' => 'tickets_paintings',
'type' => 'LEFT',
'conditions' => 'tickets_paintings.painting_id = Paintings.id'
],
'tickets' => [
'table' => 'tickets',
'type' => 'LEFT',
'conditions' => 'tickets_paintings.ticket_id = Tickets.id'
],
])
->select(['Paintings.id'])
->order(['tickets_paintings.ticket_id' => 'DESC'])
->where([
'Tickets.active' => false
]);
return $query;
}
}
然后在绘画的实体中,我检查它的ID是否在此选择内,并相应地设置一个布尔虚拟属性:
use Cake\ORM\TableRegistry;
class Painting extends Entity
{
protected function _getNotAvailable(){
$Paintings = TableRegistry::get('Paintings');
$notavailable = $Paintings->find('notavailable')
->where(['Paintings.id'=>$this->id]);
if($notavailable->isEmpty()){
// if no record --> painting is available
return 0;
} else {
// if record found --> painting is not available
return 1;
}
}
}
在视图中,我显示如下:
In Paintings - view.ctp
<?= $painting->not_available ? __('not available') : __('available'); ?>
唯一的缺点是,据我所知,虚拟属性不能用于分页。但我确信这也有解决办法。