cakephp 3.0注册与现有用户问题关联的帐户

时间:2015-04-18 07:46:06

标签: forms associations cakephp-3.0 model-validation

Accounts表具有引用Users表id的外键user_id。

我一直在尝试完成AccountsController的添加功能。目前,如果它是不存在的用户,它可以将记录添加到我的Accounts表和Users表(关联)中。当我尝试将帐户添加到现有用户时出现问题(错误我得到“在表中找不到记录”帐户“主键[NULL]”;有关此内容的更多信息)。 我有一个用户表的原因是因为它将包含公共用户(通过提供电子邮件订阅;没有帐户)和注册用户(注册用户将拥有一个帐户)。 我认为发生此问题的原因是因为电子邮件在UsersTable(规则)中不是唯一的。

AccountsController

    public function add()
    {
        $account = $this->Accounts->newEntity();
        if ($this->request->is('post')) {
            $account = $this->Accounts->patchEntity($account, $this->request->data);
            if ($this->Accounts->save($account)) {
                $this->Flash->success('The account has been saved.');
                return $this->redirect(['action' => 'index']);  
            }else {
                $this->Flash->error('The account could not be saved. Please, try again.');
            }
       }
        $users = $this->Accounts->Users->find('list', ['limit' => 200]);
        $this->set(compact('account', 'users'));
        $this->set('_serialize', ['account']);
    }

add.ctp(accounts)

        <?= $this->Form->create($account); ?>
        <fieldset>
            <legend><?= __('Add Account') ?></legend>
            <?php
                echo $this->Form->input('user.name');
                echo $this->Form->input('user.email');
                echo $this->Form->input('password');
                echo $this->Form->input('phonenumber');
                echo $this->Form->input('address');
                echo $this->Form->input('user.postcode');
            ?>
        </fieldset>
        <?= $this->Form->button(__('Submit')) ?>
        <?= $this->Form->end() ?>
    </div>

注意:有关表格在表格中的字段的信息,因此我不会详细介绍它们。但是帐户表也会有一个id和user_id; user表将具有与user_id和usertype(admin,client或public)相关联的id。

我一直试图通过尝试使用user.email从Users表中检索行来解决这个问题,但我无法访问它。如果我可以访问它,我应该能够从Users表中检索关联的行,从Users表中获取id,然后以某种方式将我的Accounts记录的user_id设置为该id。 我曾尝试从表单中请求数据,但它只适用于与帐户模型相关的输入(至少我认为它是如何工作的)。

很多人会感激不尽。如果我的想法错了,请告诉我。我非常感谢(不要求)我的问题的答案是否以外行的方式解释。

编辑:用户表将包含管理员,具有用于购买服务的注册帐户的用户以及仅想要订阅的用户。后者只需要提供比注册用户更少的信息,因此存在用户表和帐户表的原因。登录的唯一方法是使用users表(包含电子邮件)和accounts表(包含密码)。

编辑2 :我基本上想要这样做。

出现错误时的AccountsController报告地址(主键约束)

 public function add()
    {
        $account = $this->Accounts->newEntity();
        if ($this->request->is('post')) {
            $account = $this->Accounts->patchEntity($account, $this->request->data);
            if ($this->Accounts->save($account)) {
                $this->Flash->success('The account has been saved.');
                return $this->redirect(['action' => 'index']);          
            }else {
                $this->Flash->error($this->request->data['address']);
            } 

        }
        $users = $this->Accounts->Users->find('list', ['limit' => 200]);
        $this->set(compact('account', 'users'));
        $this->set('_serialize', ['account']);
    }

以上工作并报告输入的地址。

AccountsController在出现错误时报告电子邮件(主键约束)

 public function add()
    {
        $account = $this->Accounts->newEntity();
        if ($this->request->is('post')) {
            $account = $this->Accounts->patchEntity($account, $this->request->data);
            if ($this->Accounts->save($account)) {
                $this->Flash->success('The account has been saved.');
                return $this->redirect(['action' => 'index']);          
            }else {
                $this->Flash->error($this->request->data['user.email']);
            } 

        }
        $users = $this->Accounts->Users->find('list', ['limit' => 200]);
        $this->set(compact('account', 'users'));
        $this->set('_serialize', ['account']);
    }

这不起作用并给我错误: 注意(8):未定义的索引:user.email [APP / Controller \ AccountsController.php,第68行]

我想获取user.email,然后我可以在我的Users表中搜索该行并检索它的主键(插入我想要创建的帐户的user_id)。

表的SQL

 CREATE TABLE users (
          id INT AUTO_INCREMENT PRIMARY KEY,
          name VARCHAR(255),
          email VARCHAR(255),
          postcode VARCHAR(255),
          usertype VARCHAR(20) DEFAULT 'Public',
          created DATETIME,
          updated DATETIME
    );

CREATE TABLE accounts (
      id INT AUTO_INCREMENT PRIMARY KEY,
      user_id INT NOT NULL,
      password VARCHAR(255),
      phonenumber VARCHAR(10),
      address VARCHAR(255),
      created DATETIME,
      updated DATETIME,         
      FOREIGN KEY user_key (user_id) REFERENCES users(id)
);

编辑3 我发现从表单中检索关联数据的方式(或者更确切地说,修补后的实体$帐户)是通过$ account-&gt; user-&gt;电子邮件。 我正在某个地方,但这是为现有用户(公共)注册帐户的一种非常肮脏的方式。

AccountsController已更新

public function add()
    {

        $account = $this->Accounts->newEntity();
        if ($this->request->is(['post', 'patch', 'put'])) {
            $account = $this->Accounts->patchEntity($account, $this->request->data);

            if ($this->Accounts->save($account)) {
                $users = $this->Accounts->Users;
                $query = $users->query();
                $query->update()
                    ->set([
                        'usertype'=>'Client'
                    ])
                    ->where(['email' => $account->user->email])
                    ->execute();
                $this->Flash->success('The account has been saved.');
                return $this->redirect(['action' => 'index']);          

            }else {
                $users = $this->Accounts->Users;
                $query = $users->query();
                $usertype = $query->select('usertype')
                    ->where(['email' => $account->user->email]);

                    if(true){
                        $query->update()
                            ->set(['name'=>$account->user->name,
                                'postcode'=>$account->user->postcode,
                                'usertype'=>'Client'
                                ])
                            ->where(['email' => $account->user->email])
                            ->execute();
//everything up to this point works

                        $userid = $query->select('id')
                            ->where(['email' => $account->user->email]);

                        $accounts = $this->Accounts;
                        $query = $accounts->query();
                        $query->insert(['user_id', 'password', 'phonenumber', 'address'])
                            ->values([
                                'user_id' => $userid,
                                'password' => $this->request->data['password'],
                                'phonenumber' => $this->request->data['phonenumber'],
                                'address' => $this->request->data['address']
                            ])
                            ->execute();


                        $this->Flash->success('The account has been saved.');
                        return $this->redirect(['action' => 'index']);          
                    }
                    else{
                        $this->Flash->error('The account could not be saved.');
                    }
            } 

        }
        $users = $this->Accounts->Users->find('list', ['limit' => 200]);
        $this->set(compact('account', 'users'));
        $this->set('_serialize', ['account']);
    }

现在的问题是通过查询构建器将user_id输入到我的帐户行。目前,它成功地更改了我的用户的usertype,但之后当我尝试在我的Accounts表中插入一行时,我得到了这个。错误:SQLSTATE [21000]:基数违规:1241操作数应包含1列。

另外sql错误是这个 - &gt; INSERT INTO帐户(user_id,密码,电话号码,地址)VALUES((SELECT Users.usertype AS Users__usertype,Users.id AS Users__id FROM users Users WHERE(email =:c0 AND email =:c1 AND email =:c2)),: c3,:c4,:c5)

我不知道为什么它试图将两列放入一个字段中。非常感谢。 在写完这篇文章后,我意识到在有电子邮件情况的情况下执行了3个查询。似乎已加入查询。

1 个答案:

答案 0 :(得分:0)

AccountsController更新了2

公共功能add()     {

    $account = $this->Accounts->newEntity();
    if ($this->request->is(['post'])) {
        $account = $this->Accounts->patchEntity($account, $this->request->data);
        $users = $this->Accounts->Users;
        $query = $users->find();    
        $query->delete()
            ->where(['email' => $account->user->email])->where(['usertype' => 'Public'])
            ->execute();
        //the above query will delete a user if the email provided matches and their usertype is public
        //subsequently, this code will delete and add a user; not update user. ie. their id will change.    
        if ($this->Accounts->save($account)) {
            $users = $this->Accounts->Users;
            $query = $users->query();
            $query->update()
                ->set([
                    'usertype'=>'Client'
                ])
                ->where(['email' => $account->user->email])
                ->execute();
            $this->Flash->success('The account has been saved.');
            return $this->redirect(['action' => 'index']);          

        }else {
            $this->Flash->error('The account could not be saved.');
        }
    }
    $users = $this->Accounts->Users->find('list', ['limit' => 200]);
    $this->set(compact('account', 'users'));
    $this->set('_serialize', ['account']);
}

新功能将使用提供的电子邮件删除用户,其中usertype为“Public”;它只会删除1,因为电子邮件是唯一的。然后它将像往常一样用作默认的添加功能,并将新用户(或已删除但随后添加的)用户类型编辑为“客户端”。