2012-07-11 3 views
0

나는 images 테이블과 servers 테이블을 가지고 있습니다. images에는 테이블의 id 필드에 대한 외래 키인 server_id 필드가 있습니다. servers 테이블에는 name이라는 필드도 있는데이 필드는 검색하려는 필드입니다.CakePHP를 사용한 SQL JOIN

$images = $this->Image->find('all', array(
    'conditions' => array('Image.user_id' => $this->Auth->user('id')), 
    'order' => array('Image.uploaded DESC') 
)); 
$this->set('images', $images); 

그것은이 같은 데이터를 가져옵니다 :

Array 
(
    [0] => Array 
     (
      [Image] => Array 
       (
        [id] => 103 
        [orig_name] => Untitled-5.jpg 
        [hash] => MnfWKk 
        [filename] => MnfWKk.jpg 
        [uploaded] => 2012-07-12 00:09:08 
        [views] => 0 
        [album_id] => 
        [user_id] => 15 
        [server_id] => 1 
       ) 

     ) 
) 

대신 server_id, 나는 servers 테이블에서 name 필드를 얻으려면

여기 내 컨트롤러 액션 코드입니다. 어떻게하면 내 find() 방법을 적용 할 수 있습니까? 나는 이것이 SQL join이라는 것을 알고 있지만, Cake에게 서버 이름을 얻기 위해 어떻게 할 것인지를 모른다.

감사합니다.

답변

1

TLDR :

올바른 CakePHP associations을 설정하고 CakePHP's Containable를 사용합니다. (recursive-1).

긴 설명 : (당신이해야하는 경우)이 다시 컨트롤러로 이동하는 내가 보여줄 수있는 내용이지만 주시기 때문에

그것은 모델 자체에서 찾기 코드를 유지하는 가장 좋은 방법은,입니다.

이렇게하면 모든 컨트롤러에서 동일한 getImages() 함수를 호출하고 반환 할 값에 따라 다른 매개 변수를 전달할 수 있습니다. 이와 같은 코딩의 이점은 쿼리/데이터베이스와 관련된 코드를 찾고 있다면 모델을 조사해야한다는 것입니다. 코드를 보는 다음 사람이 검색 할 필요가 없을 때 매우 유용합니다.

이미지와 서버간에 연결을 설정했기 때문에 이미지를 쿼리 할 때 서버 정보를 "포함"할 수 있습니다. 그러나 모델을 $actAs = array('Containable');으로 지정하기 전까지는 "포함"을 사용할 수 없습니다. [ CakePHP Book: Containable ]

마지막으로, 귀하의 AppModel에서 $recursive = -1;을 설정하는 것이 좋습니다. 모든 모델에 대해 기본값은 -1입니다. 어떤 이유로 든 그렇게하지 않는다면, containable을 사용할 때는 항상 -1로 재귀를 설정하십시오. 그리고 - 일단 당신이 containable을 사용하는 법을 배우면, 당신은 결코 되돌아 보지 않을 것입니다 - 그것은 굉장합니다. 더 많은 것이있다 할 수 있습니다

코드 :

//AppModel ******* 
//... 
$recursive = -1; 
//... 

//Images controller ******* 
//... 
public function whatever() { 
    $opts = array(); 
    $opts['user'] = $this->Auth->user('id'); 
    $images = $this->Image->getImages($opts); 
    $this->set(compact('images')); 
} 
//... 


//Image model ******* 
//... 
public $actsAs = array('Containable'); 

public belongsTo = array('Server'); 

public function getImages($opts = array()) { 

    $params = array('condtions'=>array()); 

    //specific user 
    if(!empty($opts['user'])) { 
     array_push($params['conditions'], array('Image.user_id'=>$opts['user']); 
    } 

    //order 
    $params['order'] = 'Image.uploaded DESC'; 
    if(!empty($opts['order'])) { 
     $params['opts'] = $opts['order']; 
    } 

    //contain 
    $params['contain'] = array('Server'); 

    //returns the data to the controller 
    return $this->find('all', $params); 
} 

다른 몇 가지주의 사항 당신은 또한 당신의 서버 모델의 연결을 설정해야합니다

  • .
  • 내가 준 코드 예제는 매우 간결하게 작성되었습니다 (단어입니까?). 적합하다고 생각되는대로 응축하십시오.
  • 또한 모델의 getImages() 메소드를 확장하여 find, limit ... 등과 같은 많은 매개 변수를 허용 할 수 있습니다. 원하는대로 맞춤 설정하십시오. 일반적으로 사용하는 것과 비슷합니다.
  • 질문에 하나의 필드 만 필요한 경우 "포함"필드에서 원하는 필드를 지정할 수 있습니다. 자세한 내용은 책을 참조하십시오.
  • 지금은 혼란 스러울 지 모르겠지만, 이걸 올바르게 수행하는 방법을 배우는 것은 가치가 있습니다. 그것은 당신의 삶을 편하게 만듭니다. begginers

    $images = $this->Image->find('all', array(
        'conditions' => array('Image.user_id' => $this->Auth->user('id')), 
        'joins' => array(
            array(
             'table' => 'servers', 
             'alias' => 'Server', 
             'type' => 'inner', //join of your choice left, right, or inner 
             'foreignKey' => true, 
             'conditions' => array('Image.server_id=Server.id') 
            ), 
           ), 
        'order' => array('Image.uploaded DESC') 
    )); 
    

    에 대한

+0

에 매우 좋다. 고맙습니다. 이게 내가 케이크를 정말 사랑하게 만드는 그런 것들이라고 말해야 겠어. 나는 CodeIgniter에서 왔고 Cake는 훨씬 더 좋아 보인다. :) –

+0

Np, 기꺼이 도와 드리겠습니다. 나는 동의한다 - CakePHP는 굉장하다! – Dave

0

케익은 this을 달성하기 위해 많은 모델 관계가 있습니다. 이 페이지를 확인하십시오, 나는 당신이 belongsTo를 관계를 사용할 것입니다 생각

0

쉽고 다른 방법이이이 * 거대한 * 도움이되었습니다 성능