2012-10-11 33 views
6

Trước đây tôi đã dựa vào đệ quy, nhưng tôi đã không nhận được giải pháp cho một số, sau đó tôi thấy rằng Containable hoạt động tốt cho chúng.Thêm điều kiện vào Có thể chứa trong CakePHP

Tôi đang phát triển một trang web đánh giá phim. Trong đó tôi cần phải hiển thị danh sách các bộ phim có liên quan đến một thể loại cụ thể.

Tôi có điều này bên dưới mã:

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

Vấn đề thực sự bắt đầu ở đây, tôi nhận được tất cả các phim, thậm chí nếu nó không liên quan đến thể loại "phim". Tôi đang đi sai ở đâu?

Hãy để tôi giải thích các bảng cơ sở dữ liệu:

Bảng: phim

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

Bảng: thể loại

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

Bảng: movie_genres

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

Ở đây bạn có thể thấy rằng một mov ie_id có nhiều genre_id. Tôi sẽ chỉ nhận được mov1 nhưng tôi nhận được cả hai phim trong một mảng.

~~ EDIT ~~ oops !! xin lỗi quên đề cập đến, tôi đang sử dụng mã này trong MoviesController. Tất cả 3 bảng có bộ điều khiển tương ứng. Vì vậy, xin đề nghị tôi trong đó bộ điều khiển tôi có thể sử dụng.

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

} 

mẫu: Thể loại

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

} 

mẫu: 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

Mô hình của bạn ở đâu? –

+0

Tôi đã thêm mô hình :) –

Trả lời

13

TLDR: làm tìm bạn trên Genre và chứa nó Movies, hoặc sử dụng kết nối() - đang làm bạn Tìm kiếm r trên Phim và chứa Thể loại có điều kiện sẽ không hoạt động đối với kết quả bạn muốn.


Giải thích:

Dưới đây được sửa chữa của bạn 'chứa' mã, nhưng quan trọng hơn, làm một 'chứa' trên Genre sẽ không trả lại kết quả mà bạn đang tìm kiếm.

Điều gì làm - giới hạn các thể loại được chứa dựa trên điều kiện của bạn ... vì vậy nó sẽ kéo TẤT CẢ phim và chứa các thể loại phù hợp với $genre.


Solutions (tùy thuộc vào nhu cầu của bạn):

Giải pháp 1)

  • Thực hiện find() về thể loại, với tình trạng này, và chứa nó phim. Điều này sẽ kéo các thể loại phù hợp, sau đó chỉ có những bộ phim có liên quan đến nó.

Giải pháp 2) - một trong những tôi khuyên bạn nên

  • Sử dụng 'tham gia()':

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

bạn chỉnh sửa (sửa chữa imo) 'chứa' exampl 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. bạn không "chứa" các mô hình bạn đang làm tìm thấy trên (tức là tôi loại bỏ 'Movie' từ chứa mảng của bạn).
  2. bạn chỉ chứa các mô hình chứ không phải những thứ như "MovieGenre.Genre" (Tôi không thể nghĩ ra bất kỳ lúc nào bạn sử dụng '.' Mô hình nối)
  3. đệ quy cần phải là -1 để sử dụng Có thể chứa - bạn nên đặt này để -1 trong AppModel và quên khái niệm đệ quy - đó là xấu
+0

Tuyệt vời bro, Các tham gia làm việc hoàn hảo. Bạn có thể đề xuất một số cuốn sách nâng cao cho cakephp. Tôi không thể có bất kỳ cuốn sách nào như vậy. 'Thanks A Lot:)' hoạt động hoàn hảo, bạn bỏ lỡ một số trích dẫn ''': P –

+1

http://book.cakephp.org/2.0 thật tuyệt vời và những gì tôi đã sử dụng. – Dave

+1

Rất vui vì nó đã giúp/làm việc. Cố định các dấu ngoặc kép (có vẻ như bạn đã cố gắng quá - ty). – Dave

Các vấn đề liên quan