简体   繁体   English

CakePHP3在同一模型中将表链接在一起(内部联接)

[英]CakePHP3 Linking Table Together in Same Model (Inner Join)

i've a table named 'customers' with following (shortened) schema: 我有一个名为“客户”的表,具有以下(缩短的)模式:

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

In this table, I want to store people, which are may be associated: 在此表中,我想存储可以关联的人员:

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

Customers with "customer_id" = NULL are the master customers, but #2 and #3 refers to #1. 主客户为“ customer_id” = NULL的客户,但#2和#3指的是#1。

I've created the table in phpmyadmin and do: "bin/cake bake all customers" without errors. 我已经在phpmyadmin中创建了表,并执行了以下操作:“ bin / cake烘烤所有客户”而没有错误。 Then I created the 'master customer'. 然后,我创建了“主要客户”。 When I create the second account, I expect that the select-field shows customer #1, but the dropdown-field is empty. 当我创建第二个帐户时,我希望选择字段显示客户#1,但下拉字段为空。

The model: 该模型:

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

If you need further information or more piece of code, let me know. 如果您需要更多信息或更多代码,请告诉我。
Many thanks in advance. 提前谢谢了。

best regards 最好的祝福
Martin 马丁


SQL to reproduce 重现的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`);

Than, run 比,跑

bin/cake bake all customers

EDIT I've checked, the possible duplicate , and changed my model 编辑我检查了, 可能重复 ,并更改了我的模型

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

Now, if I try to add/edit, no changes to the select. 现在,如果我尝试添加/编辑,则对选择内容没有任何更改。 But if I view an existing customer, i got: 但是,如果我查看现有客户,则会得到:

Error: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'Customers' 错误:SQLSTATE [42000]:语法错误或访问冲突:1066不是唯一的表/别名:“客户”

This is the code for displaying the select: 这是用于显示选择的代码:

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

This code was genereated by "bin/cake bake all customers" 此代码由“ bin / cake烘烤所有客户”产生


EDIT 2 编辑2

I'll will summarize my current state: 我将总结一下我的当前状态:

Model: 模型:

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

Controller: 控制器:

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

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

If an user has an association (wife, child), the view displays a headline "Related Customers" on bottom of the page, but no additional table which shows the related customers. 如果用户有关联(妻子,孩子),则该视图在页面底部显示标题为“相关客户”的标题,但没有其他表显示相关客户。 If an user has "customer_id = 0", the view said 'Record not found in table "customers"'. 如果用户具有“ customer_id = 0”,则视图将显示“在表“ customers”中找不到记录”。

I've also added 我还添加了

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

to the add() and edit() function, but I found no way to allow also an empty value. 到add()和edit()函数,但是我发现没有办法也允许一个空值。

For clarification: Later, the front page (index()) should only list the "master customer" with customer_id = 0 with a small nested table, if he have a wife and/or children. 为了澄清起见:稍后,首页(index())仅应在有一个小嵌套表的情况下列出customer_id = 0的“主要客户”,如果他有妻子和/或孩子。

I think I am on the right way... Am I? 我想我走对了...是吗?

Thanks again in Advance 预先感谢

You should also use ParentCustomers for the first association. 您还应该将ParentCustomers用于第一个关联。 Customers duplicates itself. 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'
]);

Are you sure you did load the model already in the controller? 您确定确实已经在控制器中加载了模型吗?

Put following into controller's initialize() : $this->loadModel('Customers'); 将以下内容放入控制器的initialize()$this->loadModel('Customers');

EDIT: So it's like: 编辑:所以就像:

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

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

I've solved the issue by using CakePHPs TreeBehavior . 我已经通过使用CakePHPs TreeBehavior解决了这个问题。

I use parent_id instead of customer_id and added rght and lft column as discribed in Blog Tutorial - Part 3 . 我使用parent_id代替customer_id,并按照博客教程第3部分中的描述添加了rght和lft列。

It is working for me now! 现在为我工作! Thanks everyone! 感谢大家!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM