好的,这很难解释,但我会尽我所能。
我有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关系的例子(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')); ?>
答案 0 :(得分:6)
您有两种选择。让cakePHP与 hasAndBelongsToMany 关系做一些魔术,或者手动完成,如果你向连接表添加属性,这是必要的
使用CakePHP的功能并制定直接的解决方案,我会做出这些改变:
模型
如果一家公司有多个产品,并且这些产品属于许多公司。公司&lt; - &gt;产品
之间的 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 中插入产品,select应允许多项选择,让cakePHP做一些魔法,如下所示:
echo $this->Form->input('products', array(
'label' => 'Products to buy (Ctr+multiple choice)'
'type' => 'select',
'multiple' => true,
));
当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();
}
让我们希望这可以帮助你...
答案 1 :(得分: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);