2016-01-17 19 views
4

我是新来的CakePHP和有以下问题:CakePHP的3:结果的更改结构设置

我有表“图像”,“关键词”和“KeywordCategories”。每张图片可以有多个关键字(多对多),每个关键字都有一个类别(多对一)。检索图像列表与

$images = $this->Images->find()->contain(['Keywords', 'Keywords.KeywordCategories']); 

返回结果的结构是这样的:

[ 
    { 
     "id":1, 
     "keywords":[ 
     { 
      "keyword":"Dog", 
      "keyword_category":{ 
       "title":"Animal" 
      } 
     }, 
     { 
      "keyword":"Cat", 
      "keyword_category":{ 
       "title":"Animal" 
      } 
     }, 
     { 
      "keyword":"Black", 
      "keyword_category":{ 
       "title":"Color" 
      } 
     } 
     ] 
    } 
] 

这很好,但我想要的关键字,通过其关键词 - 类别在这样的结构中进行分组:

[ 
    { 
     "id":1, 
     "keyword_categories":[ 
     { 
      "title":"Animal", 
      "keywords":[ 
       { 
        "keyword":"Dog" 
       }, 
       { 
        "keyword":"Cat" 
       } 
      ] 
     }, 
     { 
      "title":"Color", 
      "keywords":[ 
       { 
        "keyword":"Black" 
       } 
      ] 
     } 
     ] 
    } 
] 

任何想法如何用CakePHP查询来实现?

回答

4

该格式几乎是一个反转的包含,这是不可能的只使用ORMs关联自动魔法。你将不得不单独获取相关数据,过滤它,并将其注入到图像结果中......你甚至可以创建一个自定义关联类,它包含,提取并拼接结果,但如果你问一个问题,这可能有点矫枉过正我。

因为你必须做一些额外的格式反正(并且是它只是对结果拼接在一起),我会简单地使用一些集合格式富相反,一些沿

// ... 
->find() 
->contain(['Keywords', 'Keywords.KeywordCategories']) 
->formatResults(function ($results) { 
    /* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\CollectionInterface */ 
    return $results->map(
     function ($image) { 
      $image['keyword_categories'] = 
       collection($image['keywords']) 
        ->groupBy('keyword_category.title') 
        ->map(function ($keywords, $category) { 
         foreach ($keywords as &$keyword) { 
          unset($keyword['keyword_category']); 
         } 
         return [ 
          'title' => $category, 
          'keywords' => $keywords 
         ]; 
        }) 
        ->toList(); 
      unset($image['keywords']); 
      return $image; 
     } 
    ); 
}); 

线出于说明的目的*未经测试的示例代码

即创建每个图像结果命名keyword_categories计算字段,由包含的关键词,通过其相关联的类别的标题分组,关键字嵌套在titlekeywords字段的数组中,其中类别将从关键字中删除,最后将整个事物重新索引为基本的数字索引数组。

又见

+0

太好了,那对我有效!谢谢。 – chrisch