2012-07-25 42 views
3

好吧,這是很難解釋,但我會盡我所能。cakePHP通過關係綁定hasmany

我有3個表

companies  products  product_availabilities 
---------  --------  ---------------------- 
id   id   id 
name   name   company_id 
          product_id 
          buys (tinyint) 
          sells (tinyint) 

而且他們的模型

class Company extends AppModel 
{ 
     public $name = 'Company'; 

     public $hasMany = array(
      'ProductAvailability' 
     ); 


class Product extends AppModel 
{  
    public $name = 'Product'; 

    public $hasMany = array(
     'ProductAvailability' 
    ); 


class ProductAvailability extends AppModel 
{ 
    public $name = 'ProductAvailability'; 

    public $belongsTo = array(
     'Company', 
     'Product' 
    ); 
} 

我想要做的是,當我創建一個公司,我希望能夠選擇,該公司購買產品或銷售。我在書中看到了一個hasMany through關係的例子(http://book.cakephp.org/1.3/view/1650/hasMany-through-The-Join-Model),但他們正在從「連接表「控制器。是否有可能將productAvailability模型綁定到我的公司模型上,以便能夠在創建公司時選擇產品?

編輯:這是我做到的。我知道這不是最佳的,因爲涉及到很多循環,但它很有用。

公司負責人:

$products = $this->Company->ProductAvailability->Product->find('list', array('fields' => array('Product.id', 'Product.label'))); 
    $this->set('products', $products); 

    if($this->request->is('post')){    
     if($this->Company->save($this->request->data)){ 
      foreach($products as $product) 
      { 
       $tmpArray = array(
        'company_id' => $this->Company->id, 
        'product_id' => $product['Product']['id'] 
       ); 

       foreach($this->request->data('BuyProducts.product_id') as $buyProduct) 
       { 
        if($buyProduct == $product['Product']['id']) 
         $tmpArray['buys'] = 1; 
       } 
       foreach($this->request->data('SellProducts.product_id') as $sellProduct) 
       { 
        if($sellProduct == $product['Product']['id']) 
         $tmpArray['sells'] = 1; 
       } 

       if(count($tmpArray) > 2) 
       { 
        $this->Company->ProductAvailability->create(); 
        $this->Company->ProductAvailability->set($tmpArray); 
        $this->Company->ProductAvailability->save(); 
       } 
      } 

      $this->Session->setFlash('Yay', 'success'); 
      $this->redirect(array('action' => 'index')); 
     } else { 
      $this->Session->setFlash('Nay', 'error'); 
     } 
    } 

公司地址形式:

<?php echo $this->Form->create('Company'); ?> 

<?php echo $this->Form->input('name', array('div' => 'full-form')); ?> 

<?php echo $this->Form->input('BuyProducts.product_id', array('multiple' => 'checkbox', 'options' => $products, 'div' => 'full-form', 'label' => false)); ?> 

<?php echo $this->Form->input('SellProducts.product_id', array('multiple' => 'checkbox', 'options' => $products, 'div' => 'full-form', 'label' => false)); ?> 

<?php echo $this->Form->end(array('label' => __('Save'), 'div' => 'center', 'class' => 'bouton-vert')); ?> 

回答

6

你有兩個選擇。要麼讓CakePHP的手工做一些魔法與hasAndBelongsToMany關係或做是必要的,如果你將屬性添加到連接表

1的CakePHP HABTM

使用CakePHP的能力,使一個直接的解決方案我會做這些改變:

型號

如果一個公司有多個產品,產品屬於許多公司。這是公司之間<一個hasAndBelongsToMany關係 - >產品

// company.php 
... 
var $hasAndBelongsToMany = array(
    'Product' => array(
     'className' => 'Product', 
     'joinTable' => 'companies_products', 
     'foreignKey' => 'company_id', 
     'associationForeignKey' => 'product_id', 
     'unique' => true, 
    ) 
); 
... 
// similar in product.php 

添加所需的表 'companies_products' 在數據庫中。

控制器

然後在從公司負責人那裏添加功能應該是這樣的:

$products = $this->Company->Product->find('list'); 
$this->set(compact('products')); 

查看

最後插入產品在加.ctp,選擇應該允許multipl Ë選擇,讓CakePHP的做一些神奇的,就像這樣:

echo $this->Form->input('products', array( 
         'label' => 'Products to buy (Ctr+multiple choice)' 
          'type' => 'select', 
         'multiple' => true, 
         )); 

2.手動

當HABTM變得更加「異國情調」,包括在你的情況下,「買入」或「賣出」你一些屬性,如需要做手動的方式。這是在產品控制器中將這些字段插入數據庫之前手動設置的。喜歡的東西:

foreach($availableProducts as $availableProduct){ 
    $this->Product->ProductAvailabilities->create(); 
    $this->Product->ProductAvailabilities->set(array(
    'company_id' => $this->Product->id, 
    'product_id' => $availableProduct['Product']['id'], 
    'buys' => $availableProduct['Product']['buy'], 
    'sells' => $availableProduct['Product']['sell'] 
      // or however you send it to the controller 
)); 
$this->Product->ProductAvailabilities->save(); 
} 

讓我們希望這可以幫助你......

+0

謝謝你的回答。不幸的是,hasAndBelongsToMany不適用於我的情況,因爲我想將數據保存在連接表中。一些公司會購買產品,而另一些公司則會出售它們,或者兩者都有。 – 2012-07-25 13:48:25

+0

多米尼克,我對它進行了更新,以便您可以將數據包含在連接表中。 – 2012-07-25 13:52:45

+0

我的問題是我似乎無法建立一個表格,將張貼正確的結構來保存這些數據。我必須在創建公司時保存所有這些數據。 – 2012-07-25 13:55:04

0

您計劃的habtm關係:與可能性(M n)的有連接表中的額外的字段。儘管這可以通過常規方式完成,但我更喜歡您選擇和實現m:n作爲1:n:1的方式,這種方式完全相同,並且在保存數據時爲您提供了更多選擇。

這裏是一個similar question and answer

至於你的問題:你可以從你的產品收集的數據表是這樣的:

$this->Company->ProductAvailability->Product->find('all', $params); 

你也可能想看看containable-behaviour這是對於這個用例非常有用:

$params['conditions'] = array(
    'Company.id' => $id 
); 
$params['contain'] => array(
    'ProductAvailability' => array(
     'conditions' =>array(
      'buys' => 1 
     ), 
     'Product' => array(
      'order' => array(
       'name' => 'ASC' 
      ) 
     ) 
    ) 
); 
$this->Company->find('all', $params); 
+0

謝謝。我直接將我的產品模型綁定到控制器中的我的公司。我更喜歡這種方式。 – 2012-07-25 14:25:41