【问题标题】:Cakephp 3.9 Multiple Associations with the Same TableCakephp 3.9 同一张表的多个关联
【发布时间】:2020-09-29 10:09:32
【问题描述】:

我正在使用 Cakephp 3.9,我的应用程序中有 3 个表。

CREATE TABLE `leads` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `first_name` varchar(100) NOT NULL,
 `last_name` varchar(100) NOT NULL,
 `created_dt` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

CREATE TABLE `clients` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `lead_id` int(10) NOT NULL,
 `first_name` varchar(100) NOT NULL,
 `last_name` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

CREATE TABLE `contacts` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `lead_id` int(10) NOT NULL,
 `first_name` varchar(100) NOT NULL,
 `last_name` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

Leads、Clients 和 Contacts 表之间存在一对一的关系。

我还有一个用户表:

CREATE TABLE `users` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(50) DEFAULT NULL,
 `password` varchar(255) DEFAULT NULL,
 `created` datetime DEFAULT NULL,
 `modified` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

... 和一个leads_users 表

CREATE TABLE `leads_users` (
 `lead_id` int(10) NOT NULL,
 `user_id` int(10) NOT NULL,
 `user_type` enum('Opener','Closer') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin

在我的应用程序中,用户可以作为开启者和关闭者与线索相关联。一个潜在客户可以有多个开启者和多个关闭者。我将我的模型定义如下:

class LeadsTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasOne('Contacts');

        $this->hasOne('Clients');

        $this->belongsToMany('Users', [
            'className' => 'Users'
        ])
            ->setConditions(['LeadsUsers.user_type' => 'Opener'])
            ->setProperty('openers');

        $this->belongsToMany('Users', [
            'className' => 'Users'
        ])
            ->setConditions(['LeadsUsers.user_type' => 'Closer'])
            ->setProperty('closers');
    }
}

class ClientsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsTo('Leads');
    }

}

class ContactsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsTo('Leads');
    }

}

class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Leads');
    }

}

现在在 Leads 控制器中,我正在尝试使用以下代码行查找所有潜在客户、他们的联系人、客户、开启者和关闭者。

$result = $this->Leads->find('all')->contain(['Contacts', 'Clients', 'Users']);

有了这个,我得到了更接近但不是开场白。在 LeadsT​​able 中,如果我注释掉 closeers 关联,那么我就会得到开场白。所以看起来第二个关联正在覆盖第一个。

如果我将 LeadsT​​able 关联更改为以下:

class LeadsTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasOne('Contacts');

        $this->hasOne('Clients');

        $this->belongsToMany('Openers', [
            'className' => 'Users'
        ])
            ->setConditions(['LeadsUsers.user_type' => 'Opener'])
            ->setProperty('openers');

        $this->belongsToMany('Closers', [
            'className' => 'Users'
        ])
            ->setConditions(['LeadsUsers.user_type' => 'Closer'])
            ->setProperty('closers');
    }

}

我收到以下错误:

未在线索上定义用户关联。

请让我知道我做错了什么。

提前谢谢你。

【问题讨论】:

    标签: cakephp-3.x


    【解决方案1】:

    您收到此错误是因为您还必须更改控制器查询。

    $result = $this->Leads->find('all')->contain(['Contacts', 'Clients', 'Closers','Openers']);
    

    【讨论】:

    • 感谢@Syan 的回复。我得到以下错误。错误:SQLSTATE [42S22]:找不到列:1054 'on 子句'中的未知列'LeadsUsers.closer_id' SELECT LeadsUsers.lead_id AS Closers_CJoin__lead_id,LeadsUsers.user_id AS Closers_CJoin__user_id,LeadsUsers.user_type AS Closers_CJoin__user_type,Closers .id AS Closers__id, Closers.username AS Closers__username, Closers.password AS Closers__password FROM users Closers INNER JOIN Leads_users LeadsUsers ON Closers.id = (LeadsUsers.closer_id) WHERE (LeadsUsers.lead_id in (:c0,: c1) AND LeadsUsers.user_type = :c2)
    • 它假设一个不同的连接键,closer_id。我尝试在 Leads 模型关联中将 foreignKey 指定为lead_id 并将 bindingKey 指定为 user_id,但没有成功。
    • 它仅适用于与用户表的一个关联。当我在同一个表中添加另一个“包含”时,它要么引发错误,要么覆盖以前的包含数据,要么将两者都显示为空白。
    • 您尝试过查询构建器吗?它可能会节省您查找此错误的时间
    【解决方案2】:

    所以我最终稍微更改了我的数据库并修复了它。

    CREATE TABLE `leads_openers` (
     `id` int(10) NOT NULL AUTO_INCREMENT,
     `lead_id` int(10) NOT NULL,
     `opener_id` int(10) NOT NULL,
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    
    CREATE TABLE `leads_closers` (
     `id` int(10) NOT NULL AUTO_INCREMENT,
     `lead_id` int(10) NOT NULL,
     `closer_id` int(10) NOT NULL,
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    

    然后我改变了我的模型,如下所示:

    <?php
    
    namespace App\Model\Table;
    
    use Cake\ORM\Table;
    
    class OpenersTable extends Table
    {
        public function initialize(array $config)
        {
            $this->setTable('users');
            $this->setPrimaryKey('id');
    
            $this->belongsToMany('Leads', [
                'joinTable' => 'leads_openers',
            ]);
        }
    }
    
    <?php
    
    namespace App\Model\Table;
    
    use Cake\ORM\Table;
    
    class ClosersTable extends Table
    {
        public function initialize(array $config)
        {
            $this->setTable('users');
            $this->setPrimaryKey('id');
    
            $this->belongsToMany('Leads', [
                'joinTable' => 'leads_closers',
            ]);
        }
    }
    
    
    <?php
    
    namespace App\Model\Table;
    
    use Cake\ORM\Table;
    
    class LeadsTable extends Table
    {
        public function initialize(array $config)
        {
            $this->addBehavior('Timestamp');
    
            $this->belongsToMany('Openers', [
                'joinTable' => 'leads_openers',
            ])
                ->setProperty('openers');
    
            $this->belongsToMany('Closers', [
                'joinTable' => 'leads_closers',
            ])
                ->setProperty('closers');
        }
    }
    

    然后在控制器中,我正在这样做:

    $leads = $this->Leads->find('all')
                    ->where(['Leads.status IN' => $search_condition_lead])
                    ->contain(['Contacts', 'Openers', 'Closers']);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-11
      相关资源
      最近更新 更多