我在确定在创建新用户时通过POST发送关联模型的正确(或最佳)方式时感到困惑。下面列出的两种方法都在起作用。
User hasOne UserDetails
选项1
POST数据:
{
"username": "loremipsum",
"password": "123456",
"UserDetails": {
"first_name": "Lorem",
"last_name": "Ipsum"
}
}
PatchEntity UserDetail并将其添加到用户实体,如下所示:
public function add () {
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data(), [
'associated' => [],
'validate' => true
]);
$userDetail = $this->Users->UserDetails->newEntity($this->request->data());
$user->user_detail = $userDetail;
if ($this->Users->save($user, ['associated' =>['UserDetails']]))
{
...
修改1:如果$ this-&gt; request-&gt; data()上没有UserDetails, UserDetails实体将收到验证错误。< / p>
选项2
POST数据:
{
"username": "loremipsum",
"password": "123456",
"user_detail": {
"first_name": "Lorem",
"last_name": "Ipsum"
}
}
将user_detail验证添加到UserTable.php:
编辑2:如果我没有添加user_detail验证,则可以在没有相关模型的情况下发送请求,并将保存该请求。添加它可确保$ this-&gt; request-&gt; data()上的user_detail字段和用户实体是将获得验证的字段。
$validator
->requirePresence('user_detail', 'create')
->notEmpty('user_detail');
在UsersController.php上使用和patchEntity:
public function add () {
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data(), [
'associated' => ['UserDetails'],
'validate' => true
]);
if ($this->Users->save($user, ['associated' =>['UserDetails']]))
{
...
这些方法是遵循Cake的惯例还是采用最好/最干净的方式进行?
答案 0 :(得分:0)
第二个选项是正确的选项,原因有一些:IMO。
答案 1 :(得分:0)
如果要验证多个模型,则需要根据表创建多个newEntity。这是hasOne关联的工作示例。
public function add() {
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->getData());
$userDetail = $this->UserDetails->newEntity($this->request->getData()['user_detail']);
$user->user_detail = $userDetail;
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect($this->referer());
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$this->set(compact('user'));
}