【问题标题】:CakePHP 2.5 complex find filtering by containable keyCakePHP 2.5 通过可包含键进行复杂查找过滤
【发布时间】:2014-09-27 19:28:56
【问题描述】:

我有 4 个相互连接的表

人才表

+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| id                 | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| created            | datetime         | YES  |     | NULL    |                |
| user_id            | int(10) unsigned | NO   |     | NULL    |                |
| firstname          | varchar(128)     | NO   |     | NULL    |                |
| lastname           | varchar(128)     | NO   |     | NULL    |                |
| phone_num          | varchar(32)      | NO   |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+

此表将包含诸如

之类的行
+----+-----------+------------+
| id | firstname | lastname   |
+----+-----------+------------+
|  1 | barney    | stinson    |
|  2 | Ted       | Mosby      |
+----+-----------+------------+

人才类别表

+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| id             | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| created        | datetime         | NO   |     | NULL    |                |
| talent_id      | int(10) unsigned | NO   |     | NULL    |                |
| talent_name_id | int(11)          | NO   |     | NULL    |                |
| is_active      | tinyint(1)       | NO   |     | 1       |                |
+----------------+------------------+------+-----+---------+----------------+

人才名称表

+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| created      | date             | NO   |     | NULL    |                |
| name         | varchar(128)     | NO   |     | NULL    |                |
| slug         | varchar(255)     | NO   |     | NULL    |                |
| talent_count | int(11)          | NO   |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+

此表将包含诸如

之类的行
+----+-------------------+-----------------+
| id | name              | slug            |
+----+-------------------+-----------------+
|  1 | actor / actress   | actor-actress   |
|  2 | dancer            | dancer          |
|  3 | model             | model           |
|  4 | singer / musician | singer-musician |
+----+-------------------+-----------------+

和 TalentMedia 表

+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| created      | datetime         | NO   |     | NULL    |                |
| talent_id    | int(10) unsigned | NO   |     | NULL    |                |
| media_id     | int(10) unsigned | NO   |     | NULL    |                |
| is_cover     | tinyint(1)       | NO   |     | 0       |                |
| is_avatar    | tinyint(1)       | NO   |     | 0       |                |
| like_count   | int(11)          | NO   |     | 0       |                |
| view_count   | int(11)          | NO   |     | 0       |                |
| is_published | tinyint(1)       | NO   |     | 0       |                |
| is_deleted   | tinyint(1)       | NO   |     | 0       |                |
| is_approved  | tinyint(1)       | NO   |     | 0       |                |
| is_suspended | tinyint(1)       | NO   |     | 0       |                |
+--------------+------------------+------+-----+---------+----------------+

人才hasMany TalentCategory belongsTo TalentName

人才hasMany TalentMedia

我正在努力实现

SELECT 

Talent.id,
Talent.firstname,
Talent.lastname,
TalentCategory.id,
TalentCategory.talent_id,
TalentCategory.talent_name_id,
TalentName.name,
TalentName.id,
TalentMedia.talent_id,
TalentMedia.media_id,
TalentMedia.is_suspended,
TalentMedia.is_avatar,
TalentMedia.is_cover


FROM talents AS Talent

JOIN talent_talents AS TalentCategory ON TalentCategory.talent_id = Talent.id
JOIN talent_names AS TalentName ON TalentName.id = TalentCategory.talent_name_id
JOIN talent_medias AS TalentMedia ON TalentMedia.talent_id = Talent.id

WHERE TalentName.id = 4 AND TalentMedia.is_suspended != 1 AND TalentMedia.is_cover !=1 AND TalentMedia.is_avatar = 1
GROUP BY Talent.id

select all talents which is a singer/musician that avatar is not suspended

这里有一个 SqlFiddle 描述所需的输出

来自我的控制器,以便我可以在分页器设置中实现它。我一直在尝试一切都没有运气。

我尝试了custom find typescustom query pagination,但我不太了解文档。

请帮助我了解如何实现这一目标

【问题讨论】:

  • 您的数据库结构看起来有点不对劲。如果一个 Talent hasMany TalentCategory 那么你应该分别获取 Talent 和 TalentCategory 不是吗?
  • @AngelS.Moreno 嗯,我不太明白你的问题,一个人才可以有很多人才类别(Barney stinson 是演员、歌手和舞者),这就是为什么我必须这样映射它。我更新了我的,希望它有助于解释
  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做(您还没有这样做),请提供 适当的 DDL(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
  • @Strawberry 问题是,问题不在 sql 或查询中,我可以很好地获取行,问题实际上是,我如何在 CakePHP 的 find 方法中做到这一点?无论如何,我更新了问题以提供一个小提琴

标签: mysql pagination cakephp-2.0 cakephp-2.3


【解决方案1】:

我已经设法通过创建自定义分页来完成这项工作,我不知道这是否是正确的方法,至少我的解决方案目前有效

首先我覆盖 Cake 的 paginatepaginateCount 方法

public function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {
    $recursive = -1;
    $sql_query  = $this->paginateQuery; //same query as [SqlFiddle][1]

    if(!empty($conditions)){
        $sql_query .= 'WHERE ';
        foreach ($conditions as $key => $cond) {
            $cond_str[] = $key .' '. $cond;
        }
        $sql_query .=implode(" AND ", $cond_str)." ";

    }

    $sql_query .= "GROUP BY Talent.id ";
    $sql_query .= "ORDER BY Talent.id DESC ";
    $sql_query .= "LIMIT " . (($page - 1) * $limit) . ', ' . $limit;

    $results = $this->query($sql_query);
    $this->virtualFields['fullname'] = 'CONCAT(Talent.firstname, " ", Talent.lastname)';
    return $results;
}

public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
    $recursive = -1;
    $sql_query  = $this->paginateQuery; //same query as [SqlFiddle][1]

    if(!empty($conditions)){
        $sql_query .= 'WHERE ';
        foreach ($conditions as $key => $cond) {
            $cond_str[] = $key .' '. $cond;
        }
        $sql_query .=implode(" AND ", $cond_str)." ";

    }

    $sql_query .= "GROUP BY Talent.id ";
    $sql_query .= "ORDER BY Talent.id DESC ";

    $this->recursive = $recursive;
    $this->virtualFields['fullname'] = 'CONCAT(Talent.firstname, " ", Talent.lastname)';
    $results = $this->query($sql_query);
    return count($results);
}

$this->paginateQuery; 上的值与SqlFiddle 的查询相同

我还需要稍微改变$conditions,因为它是一个数组,所以我需要以某种方式将数组连接到一些可接受的 where 条件。

在我的控制器中,我调用类似的东西

$this->Paginator->settings = array(
    'Talent' => array(
        'limit' => 1,
        'conditions' => array(
            'TalentCategory = ' => 3,
            'TalentMedia.is_suspended !=' => 1,
            'TalentMedia.is_cover     !=' => 1,
            'TalentMedia.is_avatar    = ' => 1,
            //and any other conditions related to the joined table
        )
    )
);
$this->set('talents', $this->Paginator->paginate('Talent'));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 2012-04-12
    相关资源
    最近更新 更多