2012-10-11 19 views
6

Anteriormente confiaba en recursivo, pero no encontré solución para algunos, entonces descubrí que el Containable funciona bien para estos.Agregando condiciones a Contable en CakePHP

Estoy desarrollando un sitio web de reseñas de películas. En eso necesito mostrar la lista de películas relacionadas con un género en particular.

tengo este código a continuación:

//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()); 

El problema real comienza aquí, consigo todas las películas, incluso si no es relacionado con el "drama" género. ¿Dónde me estoy equivocando?

Me explico la tabla de base de datos:

Tabla: películas

---------------------------- 
| id | title | description | 
---------------------------- 
| 1 | mov1 | something1 | 
| 2 | mov2 | something2 | 
| 3 | mov3 | something3 | 
---------------------------- 

Tabla: géneros

--------------- 
| id | name | 
--------------- 
| 1 | drama | 
| 2 | sci-fi | 
| 3 | comedy | 
--------------- 

Tabla: movie_genres

------------------------------- 
| id | movie_id | genre_id | 
------------------------------- 
| 1 | 1  | 1   | 
| 2 | 1  | 2   | 
| 3 | 2  | 2   | 
------------------------------- 

Aquí se puede ver que un mov ie_id tiene múltiples genre_id. Debería obtener solo mov1 pero obtengo ambas películas en una matriz.

~~ EDIT ~~ oops !! lo siento, olvidé mencionar, estoy usando este código en MoviesController. La tabla 3 tiene su controlador respectivo. Entonces los pls me sugieren en qué controlador puedo usar.

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' => '' 
     ), 
    ); 

} 

Modelo: Género

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' => '' 
     ) 
    ); 

} 

Modelo: 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' => '' 
     ) 
    ); 
} 
+2

¿Dónde está su modelo? –

+0

He agregado el modelo :) –

Respuesta

13

TLDR: hacer su descubrimiento en Género y contendrá sus películas, o use uniones() - haciéndolo La búsqueda en Películas y que contiene el género con condiciones no funcionará para los resultados que desee.


Explicación:

A continuación se corrige su 'contiene' código, pero lo más importante, haciendo un 'contienen' de Género no devolverá los resultados que está buscando.

Qué hace: limita los géneros contenidos en función de su condición ... por lo que extraerá TODAS las películas y contendrá los géneros que coincidan con $genre.


Soluciones (dependiendo de sus necesidades):

Solución 1)

  • hacen un find() de Género, con la condición, y contienen es películas. Esto extraerá el género que coincide, luego solo las películas que están relacionadas con él.

Solución 2) - el que yo recomiendo

  • uso 'se une a()':

$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); 

Su editado (corregido imo) 'contener' ejempl e

//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')); 
  1. no "contener" el modelo que está haciendo el hallazgo de (es decir, que eliminan 'película' de su panel contener).
  2. solo contiene modelos, no cosas como "MovieGenre.Genre" (no puedo pensar en ninguna ocasión en que usaría '.' Modelos concatenados)
  3. recurrente necesita ser -1 para usar Containable - debe establecer esto a -1 en AppModel y olvide el concepto de recursivo - es malo
+0

Impresionante hermano, The se une perfectamente. ¿Puedes sugerir algún libro avanzado para cakephp? No podría tal libro. 'Thanks A Lot:)' funciona perfecto, omite algunas de las comillas ''': P –

+1

http://book.cakephp.org/2.0 es impresionante y lo que he usado. – Dave

+1

Me alegro de que haya ayudado/trabajado. Se corrigieron las comillas (parece que usted intentó hacerlo también). – Dave