CakePHP에서 세 번째 n..n(hasAndBelongsToMany) 관계로 두 테이블을 어떻게 결합합니까?

StackOverflow https://stackoverflow.com/questions/112730

문제

나는 n...n 두 테이블의 구조, makes 그리고 models.지금까지는 문제가 없습니다.

세 번째 테이블(products) 좋다:

id
make_id
model_id
...

내 문제는 특정 제품에 대한 보기를 만드는 것입니다. make 내 안에 ProductsController 그 내용만 포함하면 모델을 만들 수 있습니다.

나는 이것이 효과가 있다고 생각했습니다.

var $uses = array('Make', 'Model');

$this->Make->id = 5; // My Make

$this->Make->find(); // Returns only the make I want with it's Models (HABTM)
$this->Model->find('list'); // Returns ALL models
$this->Make->Model->find('list'); // Returns ALL models

그래서, 내가 사용하고 싶다면 list 라디오 버튼을 만들기 위해 내 뷰로 전달하려면 다음을 수행해야 합니다. foreach()make 모든 모델 제목을 찾고 새 배열을 만들고 다음을 통해 뷰로 보내는 배열 $this->set().

$makeArray = $this->Make->find();
foreach ($makeArray['Model'] as $model) {
    $modelList[] = $model['title'];
}
$this->set('models', $models)

스트레스를 주지 않고 그 목록을 얻을 수 있는 더 쉬운 방법이 있습니까? make 정렬.내 애플리케이션에서 이러한 시나리오를 개발하는 것은 일반적인 작업이 될 것입니다.

어떤 힌트라도 미리 감사드립니다!

도움이 되었습니까?

해결책 5

해결 방법은 다음을 사용하여 얻을 수 있습니다. with 모델의 habtm 배열에서의 작업.

사용 with 다음과 같이 "중간" 테이블을 정의할 수 있습니다.

$habtm = " ...
  'with' => 'MakeModel',
   ... ";

그리고 내부적으로 모델이나 컨트롤러에서 find 방법.

보다: http://www.cricava.com/blogs/index.php?blog=6&title=modelizing_habtm_join_tables_in_cakephp_&more=1&c=1&tb=1&pb=1

다른 팁

내 힌트는 다음과 같습니다.Cake 라이브러리를 사용하여 재구성을 시도하기 전에 일반 SQL로 쿼리를 작성해 보세요.본질적으로 당신은 DB가 당신을 위해 할 수 있는 많은 추가 작업을 수행하고 있습니다.귀하의 접근 방식 (단지 쇼용 - 좋은 SQL은 아님) :

SELECT * FROM makes, models, products WHERE make_id = 5

관계를 고려하지 않습니다(Cake가 테이블의 관계를 자동으로 이해하지 않는 한).

아마도 다음을 함께 결합하는 것을 찾고 있을 것입니다.

SELECT models.title FROM models 
INNER JOIN products 
  ON products.model_id = models.model_id 
  AND products.make_id = 5

이것이 올바른 방향으로 나아가기를 바랍니다.

귀하의 의견에 따르면 귀하가 요구하는 것은 조건이 HABTM 관련 모델에 있는 특정 모델에서 결과를 얻는 방법입니다.즉.원시 SQL에서 JOIN 문을 사용하여 일반적으로 수행하는 작업입니다.
현재 그것은 Cake의 몇 안되는 약점 중 하나입니다.이를 처리하기 위한 다양한 전략이 있습니다.

  • 관련 모델 B가 모델 A에 대한 가능한 후보의 모든 ID를 반환하도록 한 다음 모델 A에 대해 두 번째 쿼리를 수행합니다.즉.:

    $this->ModelB->find('first', array('conditions' => array('field' => $condition)));
    array(
        ['ModelB'] => array( ... ),
        ['ModelA'] => array(
            [0] => array(
                'id' => 1
            )
    )
    

    이제 조건과 일치하는 ModelB에 속하는 ModelA의 모든 ID 배열이 생겼으며, Set::extract()를 사용하여 쉽게 추출할 수 있습니다.기본적으로 SELECT model_a.id FROM model_b JOIN model_a WHERE model_b.field = xxx.다음으로 ModelA를 찾습니다.

     $this->ModelA->find('all', array('conditions' => array('id' => $model_a_ids)));
    

    그것은 생산할 것입니다 SELECT model_a.* FROM model_a WHERE id IN (1, 2, 3), 이는 JOIN 문을 수행하는 우회 방법입니다.둘 이상의 관련 모델에 대한 조건이 필요한 경우 ModelA에 대한 모든 ID를 얻을 때까지 반복합니다. SQL은 모든 ID의 교차점을 사용합니다(WHERE id IN (1, 2, 3) AND id IN (3, 4, 5)).

  • ModelB에 하나의 조건만 필요하지만 ModelA를 검색하려는 경우 ModelB를 검색하면 됩니다.Cake는 관련 ModelAs를 자동으로 검색합니다(위 참조).다시 Set::extract()해야 할 수도 있지만 이미 충분할 수도 있습니다.

  • 위의 방법을 사용하고 이를 결합할 수 있습니다. 억제 가능한 행동 결과를 더 잘 제어할 수 있습니다.

  • 다른 모든 방법이 실패하거나 위의 방법으로 인해 너무 많은 오버헤드가 발생하더라도 다음을 사용하여 원시 SQL을 직접 작성할 수 있습니다. $this->Model->query().Cake SQL 표준을 고수한다면(테이블 이름을 올바르게 지정하는 경우) FROM model_as AS ModelA) Cake는 결과를 올바르게 사후 처리합니다.

이것이 당신을 올바른 방향으로 보내기를 바랍니다.

모든 다른 Make->find() 및 Model->find() 호출은 서로 완전히 독립적입니다.Make->Model->find()는 Model->find()와 동일하지만 Cake는 다른 모델에서 이미 찾은 내용을 어떤 식으로든 기억하거나 고려하지 않습니다.당신이 찾고있는 것은 다음과 같습니다 :

$this->Product->find('all', array('conditions' => array('make_id' => 5)));

$this->Make->find() 결과에서 모델 제목 목록을 가져오려면 Set::extract() 메서드를 확인하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top