在CakePHP中将条件添加到Containable

在CakePHP中将条件添加到Containable,cakephp,recursion,cakephp-2.0,conditional-statements,containable,Cakephp,Recursion,Cakephp 2.0,Conditional Statements,Containable,以前我依赖于递归,但我没有得到一些解决方案,然后我发现Containable可以很好地解决这些问题 我正在开发一个电影评论网站。在这方面,我需要显示与特定类型相关的电影列表 我有以下代码: //example $genre = "drama"; $options = array( 'contain' => array( 'Movie', 'MoveiGenre.Genre' => array( 'conditions'

以前我依赖于递归,但我没有得到一些解决方案,然后我发现Containable可以很好地解决这些问题

我正在开发一个电影评论网站。在这方面,我需要显示与特定类型相关的电影列表

我有以下代码:

//example
$genre = "drama";

$options = array(
    'contain' => array(
        'Movie',
        'MoveiGenre.Genre' => array(
            'conditions' => array('MovieGenre.Genre.name = "'.$genre.'"')
        ),
        'MovieGenre.Genre.name'
    ),
    'recursive' => 2,
    'limit' => 10
);
$this->paginate = $options;
$this->set('movies',$this->paginate());
真正的问题从这里开始,我得到了所有的电影,即使它与类型“戏剧”无关。 我哪里做错了

让我解释一下数据库表:

表:电影

 ----------------------------
 | id | title | description |
 ----------------------------
 | 1  | mov1  | something1  |
 | 2  | mov2  | something2  |
 | 3  | mov3  | something3  |
 ----------------------------
表:体裁

 ---------------
 | id | name   |
 ---------------
 | 1  | drama  |
 | 2  | sci-fi |
 | 3  | comedy |
 ---------------
表:电影类型

 -------------------------------
 | id | movie_id | genre_id    |
 -------------------------------
 | 1  | 1        | 1           |
 | 2  | 1        | 2           |
 | 3  | 2        | 2           |
 -------------------------------
在这里你可以看到一部电影id有多个流派id。我应该只得到
mov1
,但我得到的是一个数组中的两部电影

~~编辑~~ 哎呀!! 对不起,忘了提一下,我正在
MoviesController
中使用此代码。所有3个表都有各自的控制器。所以,请建议我在哪个控制器我可以使用

编辑:2

class Movie extends AppModel {
    public $displayField = 'title';

    public $actsAs = array('Containable');

    public $hasMany = array(
        'MovieGenre' => array(
            'className' => 'MovieGenre',
            'foreignKey' => 'movie_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
        'MovieLanguage' => array(
            'className' => 'MovieLanguage',
            'foreignKey' => 'movie_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
    );

}
模式:体裁

class Genre extends AppModel {

    public $displayField = 'name';

    public $hasAndBelongsToMany = array(
        'Movie' => array(
            'className' => 'Movie',
            'joinTable' => 'movie_genres',
            'foreignKey' => 'genre_id',
            'associationForeignKey' => 'movie_id',
            'unique' => 'keepExisting',
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'finderQuery' => '',
            'deleteQuery' => '',
            'insertQuery' => ''
        )
    );

}
模式:电影类型

class MovieGenre extends AppModel {

    public $belongsTo = array(
        'Movie' => array(
            'className' => 'Movie',
            'foreignKey' => 'movie_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Genre' => array(
            'className' => 'Genre',
            'foreignKey' => 'genre_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
}

TLDR:查找电影类型并包含其电影,或使用joins()-搜索电影并包含有条件的电影类型将无法获得您想要的结果


说明:

下面是您更正的“包含”代码,但更重要的是,对类型执行“包含”不会返回您要查找的结果

它的作用-根据您的情况限制包含的类型。。。因此,它将提取所有电影,并包含与
$genre
匹配的类型


解决方案(取决于您的需要):

解决方案1)

  • 根据条件对类型执行
    find()
    ,并包含它的电影。这将提取匹配的类型,然后只提取与之相关的电影
解决方案2)-我推荐的解决方案

  • 使用“joins()”:


您编辑(更正)的imo“包含”示例

//edited example
$genre = "drama";

$options = array(
    'contain' => array(
        'Genre' => array(
            'conditions' => array('Genre.name' => $genre)
        )
    ),
    'recursive' => -1,
    'limit' => 10
);
$this->paginate = $options;
$this->set('movies', $this->paginate('Movie'));
  • 您没有“包含”正在查找的模型(即我从包含数组中删除了“电影”)
  • 您只包含模型,而不包含“MovieGenre.Genre”之类的内容(我想不出任何时候您会使用“.”串联模型)
  • 递归必须是-1才能使用Containable-您应该在AppModel中将其设置为-1,并且忘记递归的概念-这很糟糕

  • 棒极了,兄弟,接头工作得很好。你能推荐一些关于cakephp的高级书籍吗。我找不到这样的书<代码>非常感谢:)工作得很好,您错过了一些
    引语:很高兴它起到了作用。修正了引号(看起来你想太多了)。我很好奇为什么你更喜欢使用连接而不是包含?@SelaYair-我不相信我说过什么更喜欢连接。在这种特殊情况下(如答案中所列),他们要么需要使用联接,要么需要更改查询的模型。选项1,选项2。没有偏好。
    //edited example
    $genre = "drama";
    
    $options = array(
        'contain' => array(
            'Genre' => array(
                'conditions' => array('Genre.name' => $genre)
            )
        ),
        'recursive' => -1,
        'limit' => 10
    );
    $this->paginate = $options;
    $this->set('movies', $this->paginate('Movie'));