Cake PHP Association

时间:2018-03-18 21:21:13

标签: php cakephp cakephp-3.0

我有3张桌子

  1. articles - 包含所有文章的列表。

  2. articles_tags - 包含所有文章标签的列表

  3. articles_tag_names - 包含标记名称列表

  4. articles表的结构为id | aticle_body | article_author_id | article_date

    articles_tags表的结构为id | article_id | article_tag_id

    articles_tag_names表的结构为id | article_tag_name

    我想使用表格关联获取所有或特定文章及其各自的标签名称。我毫无结果地尝试了以下几点。

    在App \ Model \ Table \ ArticlesTable.php。

    class ArticlesTable extends Table
    {
        public function initialize(array $config)
        {
            parent::initialize($config);
            $this->hasMany('ArticlesTags', [
                'dependent' => true,
                'cascadeCallbacks' => false,
                'propertyName' => 'article_tags'
            ]);
        }
    }
    

    在App \ Model \ Table \ ArticlesTagsTable.php。

    class ArticlesTagsTable extends Table
    {
        public function initialize(array $config)
        {
            parent::initialize($config);
            $this->belongsToMany('Articles')
            ->setForeignKey('article_id');
            /** I need ideas on how to associate with ArticlesTagNamesTable **/
        }
    }
    

    在App \ Model \ Table \ ArticlesTagNamesTable.php。

    class ArticlesTagNamesTable extends Table
    {
        public function initialize(array $config)
        {
            parent::initialize($config);
            /** I need ideas on how to associate with  ArticlesTagsTable **/
        }
    }
    

    我期待下面的输出。

      [
          [
            'id' => 145,
            'article_body' => This is my first article body,
            'article_author_id' => 13,
            'article_date' => March 18 2017 19:00:12,
            'article_tags' => [
                                [
                                  'id' => 3,
                                  'article_id' => 145,
                                  'article_tag_id' => 32,
                                  'article_tag_name' => cakephp
                                ],
                                [
                                  'id' => 4,
                                  'article_id' => 145,
                                  'article_tag_id' => 33,
                                  'article_tag_name' => java
                                ]
                              ]
          ],
          [
            'id' => 146,
            'article_body' => This is my second article body,
            'article_author_id' => 13,
            'article_date' => March 18 2017 22:00:16,
            'article_tags' =>  [
                                [
                                  'id' => 5,
                                  'article_id' => 146,
                                  'article_tag_id' => 34,
                                  'article_tag_name' => php
                                ]
                              ]
          ]
        ]
    

      [
          [
            'id' => 145,
            'article_body' => This is my first article body,
            'article_author_id' => 13,
            'article_date' => March 18 2017 19:00:12,
            'article_tags' => [
                                [
                                  'id' => 3,
                                  'article_id' => 145,
                                  'article_tag_id' => 32,
                                  'articles_tag_names' => [
                                    'id' => 12
                                    'article_tag_name' => cakephp
                                   ]
                                ],
                                [
                                  'id' => 4,
                                  'article_id' => 145,
                                  'article_tag_id' => 33,                                  
                                  'articles_tag_names' => [
                                    'id' => 13
                                    'article_tag_name' => java
                                   ]
                                ]
                              ]
          ],
          [
            'id' => 146,
            'article_body' => This is my second article body,
            'article_author_id' => 13,
            'article_date' => March 18 2017 22:00:16,
            'article_tags' =>  [
                                [
                                  'id' => 5,
                                  'article_id' => 146,
                                  'article_tag_id' => 34,
                                  'articles_tag_names' => [
                                    'id' => 14
                                    'article_tag_name' => php
                                   ]
                                ]
                              ]
          ]
        ]
    

    ....等等

    有人可以使用CakePHP关联或联接帮助组合Article,ArticleTags和ArticleTagNames。

1 个答案:

答案 0 :(得分:1)

我的第一个建议是follow CakePHP conventions轻松完成这项工作。

你最终会得到这样的东西。

文章表

CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `body` varchar(255) DEFAULT NULL,
  `author_id` int(11) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

作者表

CREATE TABLE `authors` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

标签表

CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

ArticlesTags表

CREATE TABLE `articles_tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `article_id` int(11) DEFAULT NULL,
  `tag_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx1` (`article_id`),
  KEY `idx2` (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

文章表类

<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);
        $this->setTable('articles');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');
        $this->addBehavior('Timestamp');
        $this->belongsTo('Authors', [
            'foreignKey' => 'author_id'
        ]);
        $this->belongsToMany('Tags', [
            'foreignKey' => 'article_id',
            'targetForeignKey' => 'tag_id',
            'joinTable' => 'articles_tags'
        ]);
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['author_id'], 'Authors'));
        return $rules;
    }
}

标签表类

<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;

class TagsTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('tags');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');

        $this->belongsToMany('Articles', [
            'foreignKey' => 'tag_id',
            'targetForeignKey' => 'article_id',
            'joinTable' => 'articles_tags'
        ]);
    }
}
?>

文章控制器

<?php
namespace App\Controller;

use App\Controller\AppController;

class ArticlesController extends AppController
{

    public function index()
    {
        $articles = $this->Articles->find()
            ->contain(['Authors', 'Tags'])
            ->hydrate(false)
            ->toArray();
        debug($articles);
        exit();
    }
}
?>

你最终会得到:

/src/Controller/ArticlesController.php (line 28)
[
    (int) 0 => [
        'id' => (int) 1,
        'body' => 'Lorem ipsum',
        'author_id' => (int) 1,
        'created' => object(Cake\I18n\FrozenTime) {

            'time' => '2018-03-19T00:00:25+00:00',
            'timezone' => 'UTC',
            'fixedNowTime' => false

        },
        'tags' => [
            (int) 0 => [
                'id' => (int) 1,
                'name' => 'First tag',
                '_joinData' => [
                    'id' => (int) 1,
                    'article_id' => (int) 1,
                    'tag_id' => (int) 1
                ]
            ],
            (int) 1 => [
                'id' => (int) 2,
                'name' => 'Second Tag',
                '_joinData' => [
                    'id' => (int) 2,
                    'article_id' => (int) 1,
                    'tag_id' => (int) 2
                ]
            ]
        ],
        'author' => [
            'id' => (int) 1,
            'name' => 'Xander'
        ]
    ],
    (int) 1 => [
        'id' => (int) 2,
        'body' => 'Follow CakePHP conventions!',
        'author_id' => (int) 1,
        'created' => object(Cake\I18n\FrozenTime) {

            'time' => '2018-03-19T00:00:57+00:00',
            'timezone' => 'UTC',
            'fixedNowTime' => false

        },
        'tags' => [
            (int) 0 => [
                'id' => (int) 1,
                'name' => 'First tag',
                '_joinData' => [
                    'id' => (int) 3,
                    'article_id' => (int) 2,
                    'tag_id' => (int) 1
                ]
            ],
            (int) 1 => [
                'id' => (int) 3,
                'name' => 'Third Tag',
                '_joinData' => [
                    'id' => (int) 4,
                    'article_id' => (int) 2,
                    'tag_id' => (int) 3
                ]
            ]
        ],
        'author' => [
            'id' => (int) 1,
            'name' => 'Xander'
        ]
    ]
]