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

我想做的是,当我创建公司时,我希望能够选择公司购买或销售的产品。我在书中看到了一个 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')); ?>
4

2 回答 2

6

你有两个选择。要么让 cakePHP 对hasAndBelongsToMany关系做一些魔术,要么手动做,如果你向连接表添加属性,这是必要的

1. CakePHP HABTM

使用 CakePHP 的功能并制定一个直接的解决方案,我将进行以下更改:

模型

如果一家公司有不止一种产品,并且产品属于多家公司。这是 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 

在数据库中添加所需的表“companies_products”。

控制器

然后在公司控制器的添加功能中应该有类似的内容:

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

看法

最后在add.ctp中插入产品,选择应该允许多选,让 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();
}

让我们希望这可以帮助你...

于 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 回答