3

わかりました、これを説明するのはちょっと難しいですが、最善を尽くします。

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

私がやりたいことは、会社を作るときに、その会社が購入または販売する製品を選択できるようにしたいということです。本 (http://book.cakephp.org/1.3/view/1650/hasMany-through-The-Join-Model) で hasMany スルー リレーションシップの例を見てきましたが、"テーブル結合」コントローラー。会社の作成中に製品を選択できるように、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')); ?>
4

2 に答える 2

6

2 つのオプションがあります。CakePHP にhasAndBelongsToMany関係を使って何らかの魔法を行わせるか、結合テーブルに属性を追加する場合に必要な手動で行うかのいずれかです。

1.CakePHP HABTM

CakePHP の機能を使用して、簡単なソリューションを作成するために、次の変更を行います。

モデル

1 つの会社に複数の製品があり、その製品が多くの会社に属している場合。Company<->Product 間の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 

データベースに必要なテーブル「company_products」を追加します。

コントローラ

次に、Company Controller からのadd関数には、次のようなものがあるはずです。

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

意見

最後に、製品をadd.ctpに挿入します。selectは複数の選択を許可し、cakePHP に次のような魔法を行わせる必要があります。

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

2.手動

HABTMがより「エキゾチック」になり、「購入」または「販売」のようないくつかの属性が含まれている場合は、手動で行う必要があります。これは、フィールドをデータベースに挿入する前に、手動でフィールドを設定するProduct Controllerにあります。何かのようなもの:

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

これがお役に立てば幸いです...

于 2012-07-25T13:28:55.940 に答える
0

結合テーブルに追加のフィールドを持つ可能性がある habtm-relationship (m:n) を計画しています。これは通常の habtm で実行できますが、m:n を 1:n:1 として選択して実装する方法を好みます。これは単純に同じであり、データを保存するときにより多くのオプションを提供します。

ここに同様の質問と回答があります

あなたの質問については、次のように製品テーブルからデータを収集できます。

$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);
于 2012-07-25T13:53:45.807 に答える