在CakePHP中添加条件为可容纳 [英] Adding conditions to Containable in CakePHP
问题描述
以前我是依靠递归,但我没有得到解决方案的一些,然后我发现Containable工程正常为这些。
我正在开发电影评论网站。我需要显示与特定类型相关的电影列表。
我有以下代码:
// example
$ genre =drama;
$ options = array(
'contains'=> array(
'Movie',
'MoveiGenre.Genre'=& b'conditions'=> array('MovieGenre.Genre.name ='。$ genre。'')
),
'MovieGenre.Genre.name'
),
'recursive'=> 2,
'limit'=> 10
);
$ this-> paginate = $ options;
$ this-> set('movies',$ this-> paginate());
真正的问题从这里开始,我得到所有的电影,即使它不与类型戏剧。
我在哪里出错?
让我解释数据库表:
-------------------------- -
| id |标题|描述|
----------------------------
| 1 | mov1 | something1 |
| 2 | mov2 | something2 |
| 3 | mov3 | something3 |
----------------------------
表:genres
------------ ---
| id |名称|
---------------
| 1 |戏剧|
| 2 |科幻|
| 3 |喜剧|
---------------
表: movie_genres
------------------------- ------
| id | movie_id | genre_id |
-------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
-------------------------------
在这里你可以看到一个movie_id有多个genre_id。我应该只得到 mov1
,但我得到两个电影的数组。
~~ ~~
oops!
抱歉忘了提及,我在 MoviesController
中使用这个代码。所有3表有各自的控制器。
编辑:2 p $ p> 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'=& ,
'foreignKey'=>'movie_id',
'dependent'=> false,
'conditions'=>'',
'fields'=& '',
'order'=>'',
'limit'=>'',
'offset'=>'',
'exclusive' >'',
'finderQuery'=>'',
'counterQuery'=> ''
),
);
}
型号:Genre
b $ b
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'=>'' $ b'offset'=>'',
'finderQuery'=>'',
'deleteQuery'=>'',
'insertQuery'=& b $ b)
);
}
型号:MovieGenre
b $ b
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: / strong>在Genre上找到并包含它的Movies,或使用joins() - 在Movies上搜索并包含具有条件的Genre将不会对您想要的结果起作用。
说明:
下面是您修正的包含代码,重要的是,对类型执行包含不会返回您要查找的结果。
功能 - 根据您的条件限制包含的类型。 。因此它将拉取所有电影,并包含匹配 $ genre
的类型。
解决方案(取决于您的需求):
- 在类型上执行
find()
,包含条件,并包含电影。
解决方案2)
- 使用'joins()':
$ conditions = array();
$ conditions ['joins'] = array(
array(
'table'=>'genres_movies',//或movie_genres如果您将它指定为使用
'alias'=>'GenresMovie',
'type'=>'INNER'
'conditions'=> array(
'GenresMovie.movie_id = Movie.id '
)
),
array(
'table'=>'genres',
'alias'=>'Genre',
'type'=>'INNER',
'conditions'=> array(
'Genre.id = GenresMovie.genre_id',
'Genre.name ='。$ genre 。''
)
)
);
$ this-> Movie-> find('all',$ conditions);
contains'example
//编辑示例
$ genre =drama;
$ options = array(
'contains'=> array(
'Genre'=> array(
'conditions'=& genre.name'=> $ genre)
)
),
'recursive'=> -1,
'limit'=> 10
) ;
$ this-> paginate = $ options;
$ this-> set('movies',$ this-> paginate('Movie'));
- 您不会包含发现on(即我从你的包含数组中删除'Movie')。
- 你只包含模型,而不是像MovieGenre.Genre(我不能想到任何时候,你会使用'。'连接模型)
- 递归需要为-1才能使用Containable - 应在AppModel中将其设置为-1,并忽略递归的概念 - >
Previously I was relying on recursive, but I didn't get solution for some, then I found that Containable works fine for these.
I am developing a movie review website. In that I need to show the list of movies which is related to a particular Genre.
I have this below code:
//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());
The real problem starts here, I get all the movies, even if its not related to the genre "drama". Where am I going wrong ?
Let me explain the database table:
Table: movies
----------------------------
| id | title | description |
----------------------------
| 1 | mov1 | something1 |
| 2 | mov2 | something2 |
| 3 | mov3 | something3 |
----------------------------
Table: genres
---------------
| id | name |
---------------
| 1 | drama |
| 2 | sci-fi |
| 3 | comedy |
---------------
Table: movie_genres
-------------------------------
| id | movie_id | genre_id |
-------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
-------------------------------
Here you can see that one movie_id has multiple genre_id. I should get only mov1
but I'm getting both movies in an array.
~~ EDIT ~~
oops!!
sorry forgot to mention, I'm using this code in MoviesController
. All 3 table has respective controller. So pls suggest me in which controller I can use.
EDIT: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' => ''
),
);
}
Model: Genre
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' => ''
)
);
}
Model: MovieGenre
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: do your find on Genre and contain it's Movies, or use joins() - doing your search on Movies and containing Genre with conditions won't work for the results you want.
Explanation:
Below is your corrected 'contain' code, but more importantly, doing a 'contain' on Genre won't return the results you're looking for.
What it does - limits the contained genres based on your condition... so it will pull ALL movies, and contain the genres that match $genre
.
Solutions (depending on your needs):
Solution 1)
- Do a
find()
on Genre, with the condition, and contain it's movies. This will pull the genre that matches, then only the movies that are related to it.
Solution 2) - the one I'd recommend
- Use 'joins()':
$conditions = array();
$conditions['joins'] = array(
array(
'table' => 'genres_movies', //or movie_genres if you've specified it as the table to use
'alias' => 'GenresMovie',
'type' => 'INNER'
'conditions' => array(
'GenresMovie.movie_id = Movie.id'
)
),
array(
'table' => 'genres',
'alias' => 'Genre',
'type' => 'INNER',
'conditions' => array(
'Genre.id = GenresMovie.genre_id',
'Genre.name = "' . $genre . '"'
)
)
);
$this->Movie->find('all', $conditions);
Your edited (corrected imo) 'contain' example
//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'));
- you don't "contain" the model you're doing the find on (ie I removed 'Movie' from your contain array).
- you only contain models, not things like "MovieGenre.Genre" (I can't think of any time you would use '.' concatenated models)
- recursive needs to be -1 to use Containable - you should set this to -1 in the AppModel and forget the concept of recursive - it's bad
这篇关于在CakePHP中添加条件为可容纳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!