CakePHP 3:包含COUNT()的深度关联模型

时间:2015-11-03 19:43:07

标签: cakephp orm cakephp-3.0

我有以下相关的表格对象:

SettingsTable belongsTo SettingsHeadersTable

SettingsHeadersTable hasMany SettingsTable

SettingsOptionsTable belongsTo SettingsTable

SettingsTable hasMany SettingsOptionsTable

例如:

  • 标题为"常规网站设置"。
  • 标题为"离线状态"。
  • 的标题下有一个设置
  • 在该设置下有3个选项用于"在线","离线 (限制)" on"离线(不受限制)"

我有一个控制器,我想找到所有标题,包含这些标题下的所有设置,并进一步包含这些设置下的所有选项。然后在我看来,我可以遍历每个设置,按标题分为几个部分,并显示每个设置的相应选项,供管理员更新。

下面,我的原始查询会准确显示上面描述的内容,但是,即使它们有0个可见设置,它也会显示标题。我想隐藏具有0个可见设置的标题。

    $settings_headers = $this->Settings->SettingsHeaders->find()
    ->order([
        'SettingsHeaders.number' => 'ASC'
    ])
    ->where([
        'SettingsHeaders.module_id' => 1
    ])
    ->contain([
        'Settings' => function ($q) {
           return $q
                ->order(['Settings.number' => 'ASC'])
                ->where([
                    'Settings.hide' => 0
                ])
                ->contain([
                    'SettingsOptions' => function ($q) {
                       return $q
                             ->order(['SettingsOptions.number' => 'ASC']);
                    }
                ]);
        }
    ])

    ->toArray();

我进行了一些调整并进入标题,只显示可见的设置以及相应的设置,但选项未显示。我对包含与匹配仍然非常困惑。我不确定我写的代码是否多余,我一直试图效法我在网上看过的例子。

    $settings_headers = $this->Settings->SettingsHeaders->find()
    ->order([
        'SettingsHeaders.number' => 'ASC'
    ])
    ->where([
        'SettingsHeaders.module_id' => 1
    ])
    ->select([
        'SettingsHeaders.id',
        'SettingsHeaders.title',
        'SettingsHeaders.number',
        'SettingsHeaders.module_id',
        'settings_count' => 'COUNT(Settings.id)',                               
    ])
    ->select($this->Settings)
    ->group('SettingsHeaders.id')
    ->contain([
        'Settings' => function ($q) {
           return $q
                ->order(['Settings.number' => 'ASC'])
                ->where([
                    'Settings.hide' => 0 // ONLY SHOW VISIBLE SETTINGS
                ])
                ->contain([
                    'SettingsOptions' => function ($q) {
                       return $q
                             ->order(['SettingsOptions.number' => 'ASC']);
                    }
                ]);
        }
    ])
    ->matching('Settings', function($q) {
        return $q->where([
            'Settings.hide' => 0 // ONLY COUNT THE VISIBLE SETTINGS
        ]);
    })
    ->toArray();

我不太确定如何将它们放在一起(仅显示带有可见选项的标题,还包含Settings和SettingsOptions中的所有数据)

1 个答案:

答案 0 :(得分:0)

实际上,我只想出了这个。我不得不从第二个例子中删除以下行:

->select($this->Settings)