2017-04-07 1 views
0

MAMP에서 실행중인 Cake PHP 3.4.Cake PHP 3.4 - 동일한 쿼리에 2 개의 내부 조인을 추가하는 방법은 무엇입니까?

SQL 테이블

TABLE `Ingredients` (
    `id` int(11) NOT NULL, 
    `name` varchar(255) NOT NULL, 
    `category_id` int(11) NOT NULL, 
    `measure_id` int(11) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 


Table products 
TABLE `Products` (
    `id` int(11) NOT NULL, 
    `name` varchar(255) NOT NULL, 
    `retail_price` float NOT NULL, 
    `best_before` int(11) NOT NULL, 
    `comments` text NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 



TABLE `ingredients_products` (
    `ingredient_id` int(11) NOT NULL, 
    `product_id` int(11) NOT NULL, 
    `qty` double NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

표 모델 : 나는 다음과 같은 시나리오가 CakePHP의에

class IngredientsTable extends Table 
{ 

    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->setTable('ingredients'); 
     $this->setDisplayField('name'); 
     $this->setPrimaryKey('id'); 

     $this->hasMany('Purchases', [ 
      'foreignKey' => 'ingredient_id' 
     ]); 
     $this->hasMany('IngredientsProducts', [ 
      'foreignKey' => 'ingredient_id' 
     ]); 
    } 

class ProductsTable extends Table 
{ 

    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->setTable('products'); 
     $this->setDisplayField('name'); 
     $this->setPrimaryKey('id'); 

     $this->hasMany('IngredientsProducts', [ 
      'foreignKey' => 'product_id' 
     ]); 
    } 

을, 나는 국지적 인 논리를 (내 시나리오에 적응)이 cookbok의 북마크 자습서를 것 다음 많은 성분이있는 제품이 있어야합니다. 이것은 굽기 후에 잘 작동하는 것처럼 보입니다.

내가 원하는 것은 : 특정 제품에 대한 제품보기에서 (제품 ID와 관련된) 제품 필드뿐만 아니라 재료를 표시하고자합니다. 제 코드를 그대로 사용하면 제품 필드 (괜찮습니다)가 표시되지만 joiner 테이블의 해당 제품 ID 만 표시됩니다.

public function view($id = null) 
    { 
     $product = $this->Products->get($id, [ 
      'contain' => ['IngredientsProducts'] 
     ]); 

     $this->set('product', $product); 
     $this->set('_serialize', ['product']); 



    } 

SQL에서 내가 실행됩니다 쿼리입니다 : 내가 쿼리 빌더 페이지에서 볼 것을 노력했습니다

SELECT products.name as prod, ingredients.name as ingr, ingredients_products.qty as qty 
FROM ingredients_products 
    INNER JOIN products 
     ON ingredients_products.product_id = products.id 
    INNER JOIN ingredients 
     ON ingredients_products.ingredient_id = Ingredients.id 

:

는하지만 난 아무것도 찾을 수 없습니다 https://book.cakephp.org/3.0/en/orm/query-builder.html을 그 그런 질문을 할 수있게 해줄거야. 누구나 어떻게 달성 할 수 있는지 알고 있습니까?

감사합니다!

답변

0

이 많이 들린다 그래서 당신은 IngredientsProductsTable 모델이있을 것이다.

class IngredientsTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     // Use through option because it looks like you 
     // have additional data on your IngredientsProducts table 
     $this->belongsToMany('Products', [ 
      'through' => 'IngredientsProducts', 
     ]); 
    } 
} 

class ProductsTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     $this->belongsToMany('Ingredients', [ 
      'through' => 'IngredientsProducts', 
     ]); 
    } 
} 

class IngredientsProductsTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     $this->belongsTo('Ingredients'); 
     $this->belongsTo('Products'); 
    } 
} 
+0

이것은 트릭을 만들었습니다. 고맙습니다! belongsToMany에 대해 읽었지만이 예제에서 구현하는 방법을 알지 못했습니다. – Tzi

0

내가 완전히 달성하고자 팔로우 모르겠지만, 당신은 단지 특정 제품에 대한 모든 재료를 원하는 경우이 같은 제품의 Ingredientscontain 수 있습니다 : -

$product = $this->Products->get($id, [ 
    'contain' => ['Ingredients'] 
]); 

그러나 , 질문에 설명 된 SQL 쿼리를 수행하려면 조인 테이블의 모델을 정의한 다음이를 쿼리 할 수 ​​있습니다. 컨트롤러에서 다음

class IngredientsProductsTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     $this->belongsTo('Ingredients'); 
     $this->belongsTo('Products'); 
    } 
} 

: - - : A가 속한 많은 관계를 가지고 같은

$this->loadModel('IngredientsProducts'); 
$data = $this->IngredientsProducts->find('all') 
    ->contain(['Ingredients', 'Products']); 
+0

안녕하세요! 답변 주셔서 감사합니다. 미안하지만 내 질문에 분명하지 않다. 제가하려는 것은 특정 제품에 대한보기를 열 때 해당보기에서 해당 제품과 관련된 모든 재료를 결합 자 테이블 ingredients_products대로 표시하고자합니다. IngredientsProductsTable 모델을 정의하려고 시도했지만 지금은 모든 제품을 얻습니다. 어떻게하면 $ this-> loadModel ('IngredientsProducts')을 수정할 수 있습니까? $ data = $ this-> IngredientsProducts-> find ('all') -> 포함 ([ 'Ingredients', 'Products']); 특정 제품 ID를 찾으십니까? 감사! – Tzi

+0

그 경우 첫 번째 예제를 사용하고 성분을 '포함'해야합니다. 그러면 조인 테이블을 사용하여 반환되는 제품에 대한 관련 구성 요소를 검색합니다. – drmonkeyninja

+0

좋아요! 하지만 이상한데, 첫 번째 예제를 사용할 때 "제품이 성분과 관련이 없습니다"오류가 발생합니다. – Tzi

관련 문제