2017-04-07 5 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に関連する)を表示するだけでなく、成分も表示したいと考えています。 私のコードはそのままですが、製品フィールド(okです)を表示していますが、結合ツールテーブルの関連するIDだけが表示されていますproducts_products。 SQLで

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

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



    } 

私が実行しますクエリは次のとおりです。

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

: - - :に属し、多くの関係を持っているよう

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

こんにちは!あなたの答えをありがとう。申し訳ありませんが私は私の質問ではっきりしていない場合。私がしようとしていることは、特定の製品のビューを開くと、そのビューでは、その製品に関連するすべての成分を、結合ツールのテーブルproducts_productsごとに表示することです。 IngredientsProductsTableというモデルを定義しようとしましたが、今はすべての製品を手に入れました。どうすれば$ this-> loadModel( 'IngredientsProducts')を変更できますか。 $ data = $ this-> IngredientsProducts-> find( 'all') - > contains(['Ingredients'、 'Products']);特定の製品IDを探す?ありがとう! – Tzi

+0

その場合、私の最初の例を使用し、成分を '含む '必要があります。これは、ジョイン・テーブルを使用して、返される製品の関連する成分を検索します。 – drmonkeyninja

+0

素晴らしい!しかし、最初の例を使用すると「製品が成分と関連していません」というエラーが出るのは奇妙です。 – Tzi

関連する問題