【问题标题】:'Through' association with 'foreign_key' & 'model' fields in CakePHP 3CakePHP 3 中与“foreign_key”和“模型”字段的“通过”关联
【发布时间】:2015-04-15 06:35:25
【问题描述】:

这是一个相当标准的事情,我在 CakePHP 2 中可能已经做了 600 次,但在我的一生中,我无法让它在 CakePHP 3 中工作。

我有Videos、Photos、Articles。我也有Categories。

视频、照片和文章都可以属于一个或多个类别。

当前问题的目标是拉取某个类别下的视频。

所以,我尝试了这个:

// VideosTable
$this->belongsToMany('Categories', [
    'joinTable' => 'categorized',
    'className' => 'Categorized',
    'foreignKey' => 'foreign_key',
    'conditions' => [
        'Categorized.model' => 'Videos',
    ]
]);

public function getTopVideosByCategory($categorySlug)
{
    return $this->Categories->find('all')
        ->where(['Categories.slug' => $categorySlug])
        ->contain([
            'Videos' => function ($q) {
                return $q
                    ->limit(8)
                    ->contain([
                        'Tags',
                        'Categories' // tried with and without this
                    ])
                    ->order([
                        'Videos.featured' => 'DESC',
                        'Videos.created' => 'DESC'
                    ]);
            }
        ])
        ->first();
}

错误:SQLSTATE[42S22]:找不到列:1054 未知列 'where 子句'中的'Categorized.model'

我尝试了许多其他方法,包括创建连接表的模型和其他一些方法,但不断出错。我已经尝试了每个选项,并且选项数量有限。我尝试过使用实际的 Table 类,也尝试过伪类(如上面的“Categorized”)。

我不得不假设这是相当标准的,但在书中找不到示例,而且我似乎无法让它发挥作用。


编辑:

我也试过这个:

//VideosTable
public function initialize(array $config)
{
    $this->belongsToMany('Categories', [
        'through' => 'Categorized',
        'conditions' => [
            'Categorized.model' => $this->alias(),
        ]
    ]);
}

public function getTopVideosByCategory($categorySlug)
{
    return $this->find('all')
        ->matching('Categories', function ($q) use ($categorySlug) {
            return $q
                ->where(['Categories.slug' => $categorySlug]);
        })
        ->contain([
            'Tags',
            'Categories'
        ])
        ->limit(8)
        ->order([
            'Videos.featured' => 'DESC',
            'Videos.created' => 'DESC'
            ])
        ->first();
}

但是得到这个错误:

错误:SQLSTATE[42S22]:找不到列:1054 未知列 'on 子句'中的'Categorized.model'

【问题讨论】:

  • Categorized 的表架构是什么样的?
  • 分类只是id (CHAR 36), foreign_key (CHAR 36), model (VARCHAR 60), category_id (CHAR 36)

标签: php mysql cakephp associations cakephp-3.0


【解决方案1】:

由于视频和类别不是 1-1 o n-1(hasOne 或 belongsTo),因此不可能构建一个可以包含其他表条件的 SQL 表达式。对于这些情况,CakePHP 实现了matching() 函数。它的工作方式类似于contain(),但它的作用是使用内部连接从外部关联中获取数据:

http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#filtering-by-associated-data

您也可以在此处查看使用它的示例:

http://book.cakephp.org/3.0/en/tutorials-and-examples/bookmarks/intro.html#creating-the-finder-method

【讨论】:

  • 重新阅读您的问题后,我添加了另一个答案,因为我认为我误解了
  • 我不确定哪个答案是新答案,但我无法工作。当我尝试使用->matching 时,我得到Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Categorized.model' in 'on clause'。我是否还需要使用手册 ->join() 选项?书中的例子很好,但似乎不一样,因为它是从关联模型中提取的(我假设)。在这种情况下,即使我说我想使用“分类”作为through 模型,它表示它们没有关联。当我尝试在视频上执行 ->where() 时,它也会引发错误。
  • 我已经根据建议和阅读建议的书籍部分更新了我的问题和我最近的尝试。我一定还没有抓住什么。
【解决方案2】:

我最终让它像这样工作:

class VideosTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasMany('Categorized', [
            'foreignKey' => 'foreign_key',
            'conditions' => [
                'Categorized.model' => $this->alias(),
            ]
        ]);
    }

    public function getTopVideosByCategory($categorySlug)
    {
        return $this->find()
            ->matching(
                'Categorized.Categories', function ($q) use ($categorySlug) {
                    return $q
                        ->where(['Categories.slug' => $categorySlug]);
            })
            ->limit(8)
            ->order([
                'Videos.featured' => 'DESC',
                'Videos.created' => 'DESC'
                ])
            ->all();
    }

我对 José 的回答投了赞成票,因为它引导我找到了答案,但我认为它会更快速地帮助用户解决这个特殊问题。

José,如果您想将此(以及您认为合适的任何调整)附加到您的答案中,我会将标记的答案更改为您的答案。

【讨论】:

    【解决方案3】:

    看来你想要的是:

    $this->belongsToMany('Categories', [
        'through' => 'Categorized',
        'conditions' => ['Categorized.model' => $this->alias()]
    ]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 2018-02-15
      • 2017-08-14
      相关资源
      最近更新 更多