CakePHP3在同一模型中连接表(内部连接)

时间:2016-02-24 09:03:00

标签: php mysql cakephp cakephp-3.0

我有一张名为'客户'使用以下(缩短的)架构:

id | customer_id | type | salutation | forename | surname | created | modified

在此表中,我想存储可能关联的人员:

id | customer_id | type    | salutation | forename | surname | created             | modified
 1 | NULL        | husband | Mr.        | John     | Doe     | 2016-01-05 10:00:00 | 2016-01-05 10:00:00
 2 |  1          | wife    | Mrs.       | Jane     | Doe     | 2016-01-05 10:01:00 | 2016-01-05 10:01:00
 3 |  1          | child   | Mr.        | Jim      | Doe     | 2016-01-05 10:02:00 | 2016-01-05 10:02:00

拥有" customer_id"的客户= NULL是主客户,但#2和#3引用#1。

我已经在phpmyadmin中创建了表格并执行: " bin / cake烘焙所有顾客"没有错误。 然后我创建了“主客户”#39;。当我创建第二个帐户时,我希望select-field显示客户#1,但下拉字段为空。

模特:

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('customers');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsTo('Customers', [
        'foreignKey' => 'customer_id',
        'joinType' => 'INNER'
    ]);
    $this->hasMany('Customers', [
        'foreignKey' => 'customer_id'
    ]);
}

如果您需要更多信息或更多代码,请与我们联系 提前谢谢了。

最好的问候 马丁

要重现的SQL

CREATE TABLE IF NOT EXISTS `customers` (
  `id` int(11) NOT NULL,
  `typ` varchar(10) NOT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `salutation` varchar(4) NOT NULL,
  `prename` varchar(255) NOT NULL,
  `surname` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

INSERT INTO `customers` (`id`, `typ`, `customer_id`, `salutation`, `prename`, `surname`, `created`, `modified`) VALUES
(1, 'husband', NULL, 'Mr.', 'John', 'Doe', '2016-03-02 21:26:32', '2016-03-02 21:26:32'),
(2, 'wife', 1, 'Ms.', 'Jane', 'Doe', '2016-03-02 21:27:25', '2016-03-02 22:10:05'),
(3, 'child', 1, 'Mr.', 'Jim', 'Doe', '2016-03-02 21:27:41', '2016-03-02 22:10:15');

ALTER TABLE `customers` ADD PRIMARY KEY (`id`), ADD KEY `customers_fk0` (`customer_id`);
ALTER TABLE `customers` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4;
ALTER TABLE `customers` ADD CONSTRAINT `customers_fk0` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`);

然后,运行

bin/cake bake all customers

修改 我已经检查了possible duplicate,并更改了我的模型

$this->belongsTo('Customers', [
    'foreignKey' => 'customer_id',
    'joinType' => 'INNER'
]);
$this->hasMany('ChildCustomers', [ // <-- changed this line
    'className' => 'Customers',    // <-- added this line
    'foreignKey' => 'customer_id'
]);

现在,如果我尝试添加/编辑,则不会对选择进行任何更改。但如果我查看现有客户,我得到了:

  

错误:SQLSTATE [42000]:语法错误或访问冲突:1066不是   独特的表/别名:&#39;客户&#39;

这是显示选择的代码:

echo $this->Form->input('customer_id');

此代码由&#34; bin / cake烘焙所有客户&#34;

生成

编辑2

我将总结一下我目前的状态:

型号:

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('customers');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsTo('ParentCustomers', [
        'className' => 'Customers',
        'foreignKey' => 'customer_id',
        'joinType' => 'INNER'
    ]);
    $this->hasMany('ChildCustomers', [
        'className' => 'Customers',
        'foreignKey' => 'customer_id'
    ]);
}

public function buildRules(RulesChecker $rules)
{
    $rules->add($rules->existsIn(['customer_id'], 'ParentCustomers'));
    return $rules;
}

控制器:

public function view($id = null)
{
    $customer = $this->Customers->get($id, [
        'contain' => ['ParentCustomers']
    ]);

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

如果用户有关联(妻子,孩子),则该视图会显示标题&#34;相关客户&#34;在页面底部,但没有显示相关客户的附加表。如果用户有&#34; customer_id = 0&#34;,该视图表示&#39;记录未在表格中找到&#34;客户&#34;&#39;。

我还添加了

$this->set('customers', $this->Customers->find('list'));

到add()和edit()函数,但我发现无法允许空值。

澄清: 之后,首页(index())应该只列出&#34;主客户&#34;如果他有妻子和/或孩子,则使用带有小型嵌套表的customer_id = 0。

我想我的方式正确......我呢?

再次感谢您提前

3 个答案:

答案 0 :(得分:0)

您还应该使用ParentCustomers作为第一个关联。 Customers重复自己。

$this->belongsTo('ParentCustomers', [ // <-- You need to change here
    'className' => 'Customers', // <-- You need to change here
    'foreignKey' => 'customer_id',
    'joinType' => 'INNER'
]);
$this->hasMany('ChildCustomers', [
    'className' => 'Customers',
    'foreignKey' => 'customer_id'
]);

答案 1 :(得分:0)

您确定已加载控制器中已存在的模型吗?

将以下内容放入控制器的initialize()$this->loadModel('Customers');

编辑:所以就像:

    public function initialize()
    {
        parent::initialize();

        $this->loadModel('Customers');
    }

答案 2 :(得分:0)

我使用CakePHPs TreeBehavior解决了这个问题。

我使用parent_id而不是customer_id,并添加了Blog Tutorial - Part 3中描述的rght和lft列。

现在正在为我工​​作!谢谢大家!