cakephp 3.0 注册与现有用户问题关联的帐户
Posted
技术标签:
【中文标题】cakephp 3.0 注册与现有用户问题关联的帐户【英文标题】:cakephp 3.0 Registering an account associated to an existing user issue 【发布时间】:2015-04-18 07:46:06 【问题描述】:Accounts 表有外键 user_id,它引用了 Users 表 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(帐户)
<?= $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>
注意:有关表格中哪些字段的信息,因此我不会详细介绍它们。但是accounts表也会有id和user_id;用户表将具有与 user_id 关联的 id 和用户类型(管理员、客户端或公共)。
我一直在尝试通过使用 user.email 从 Users 表中检索行来解决此问题,但我无法访问它。如果我可以访问它,我应该能够从 Users 表中检索关联的行,从 Users 表中获取 id,然后以某种方式将我的 Accounts 记录的 user_id 设置为该 id。 我曾尝试从表单中请求数据,但它仅适用于与帐户模型相关的输入(至少我认为它是这样工作的)。
我们将不胜感激。请告诉我我的想法是否错误。如果我的问题的答案能以通俗易懂的方式解释,我将不胜感激(不是要求)。
编辑:用户表将包含管理员、拥有注册帐户以购买服务的用户和只想订阅的用户。后者只需要提供比注册用户更少的信息,因此为什么同时存在用户表和帐户表。登录的唯一方法是使用用户表(包含电子邮件)和帐户表(包含密码)。
编辑 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, line 68]
我想获取 user.email,这样我就可以在我的用户表中搜索该行并检索它的主键(插入我尝试创建的帐户的 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->user->email 从表单(或更准确地说,修补的实体 $account)中检索相关数据的方法。 我正在取得进展,但这是为现有用户(公共)注册帐户的一种非常肮脏的方式。
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 输入到我的帐户行中。目前,它成功地更改了我的用户的用户类型,但是当我尝试在我的帐户表中插入一行时,我得到了这个。错误:SQLSTATE[21000]:基数违规:1241 操作数应包含 1 列。
另外 sql 错误是这个 -> INSERT INTO accounts (user_id, password, phonenumber, address) VALUES ((SELECT Users.usertype AS Users__usertype
, Users.id AS Users__id
FROM users Users WHERE (email = : c0 AND 电子邮件 = :c1 AND 电子邮件 = :c2)), :c3, :c4, :c5)
我不知道为什么它试图将两列放在一个字段中。很多帮助表示赞赏。 在写这篇文章时,我意识到有 3 个查询执行到存在电子邮件条件的那一点。似乎查询已加入。
【问题讨论】:
收到错误时,请始终显示完整的错误消息,包括堆栈跟踪!此外,“我无法访问它”不是正确的问题描述,它可能意味着任何事情,如果您尝试过某些事情,那么请将代码添加到您的问题中并解释究竟出了什么问题。顺便说一句,谁在添加这些“帐户”,即“用户”自己?如果是,他们当时是否已经通过身份验证/登录? 用户没有登录。用户唯一可用的功能是添加他们的详细信息以订阅时事通讯。帐户将具有登录功能。说明一下,目前还没有登录功能(待账户添加功能完成后实现)。尝试从我的帐户表单请求用户 (user.email) 数据时出现的错误是 Notice (8): Undefined index: user.email [APP/Controller\AccountsController.php, line 68] 【参考方案1】: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']);
新功能将删除用户类型为“Public”的提供电子邮件的用户;它只会删除 1,因为电子邮件是唯一的。然后它将像默认添加功能一样正常运行,并将新用户(或删除然后添加)的用户类型编辑为“客户端”。
【讨论】:
以上是关于cakephp 3.0 注册与现有用户问题关联的帐户的主要内容,如果未能解决你的问题,请参考以下文章