Cakephp 3:在belongsToMany关联

时间:2015-11-01 20:02:34

标签: php mysql cakephp

我有两张桌子,门票和绘画。一张票可以有许多画作,许多票可以使用一幅画。他们有一个名为 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)是否可行或是否可取的"在实体内检查这样的事情吗?

我首先尝试在绘画表中使用额外的数据库字段,但每次编辑故障单时检查并设置另一个值似乎要复杂得多(不是我设法使其工作)...和票价和绘画的活跃价值几乎翻了一番。所以我认为虚拟财产更容易处理。还是我在完全错误的火车上?

感谢您对此噩梦的任何提示或建议=)!

1 个答案:

答案 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'); ?>

唯一的缺点是,据我所知,虚拟属性不能用于分页。但我确信这也有解决办法。