我有一个带有两个关联模型的应用程序:用户和课程,它们与HABTM协会相关。
有一个注册表单,新用户可以输入用户名并选择他们所属的课程(从数据库中的现有课程列表中),只有表单只保存新用户 - 它不会将任何内容保存到连接表中。
联接表(courses_users
)包含course_id
列和user_id
列,两个模型如下所示:
// User.php
class User extends AppModel {
public $name = 'User';
public $hasAndBelongsToMany = array(
'Courses' => array(
'className' => 'Course',
'joinTable' => 'courses_users',
'foreignKey' => 'user_id',
'associatedForeignKey' => 'course_id'
)
);
}
// Course.php
class Course extends AppModel {
public $name = 'Course';
public $hasAndBelongsToMany = array(
'Users' => array(
'className' => 'User',
'joinTable' => 'courses_users',
'foreignKey' => 'course_id',
'associatedForeignKey' => 'user_id'
)
);
}
此外,这是控制器操作:
// IdentificationController.php
public function register() {
if ($this->request->is('POST')) {
$data = $this->request->data;
$username = $data['User']['username'];
$saved = $this->User->save($data, array('deep' => true));
//debug($data);
if ($saved) {
$this->_set_new_user_session($username);
//$log = $this->User->getDataSource()->getLog(false, false);
//debug($log);
$this->redirect(array('controller' => 'users', 'action' => 'index'));
}
}
// Not redirecting
$courses = $this->Course->find('list', array('Course.name'));
//debug($courses);
$this->set(compact('courses'));
}
这是形式,没有容器div:
<?php
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
),
'url' => '/identification/register'
));
echo $this->Form->input('username', array(
'error' => false,
'autofocus' => true,
'required' => true,
'pattern' => '[a-zA-Z0-9]{3,16}'
));
if ($this->Form->isFieldError('username')) {
echo $this->Form->error('username', null, array('wrap' => 'small', 'class' => 'error'));
}
echo $this->Form->input('Course.Course', array(
'error' => false,
'required' => true
));
if ($this->Form->isFieldError('courses')) {
echo $this->Form->error('course', null, array('wrap' => 'small', 'class' => 'error'));
}
echo $this->Form->button('Register', array(
'div' => false,
'type' => 'submit'
));
echo $this->Form->end();
?>
当我调用debug($ data)时,正确的数据似乎从表单传递给控制器:
array(
'User' => array(
'username' => 'test63apd'
),
'Course' => array(
'Course' => array(
(int) 0 => '1'
)
)
)
但是连接表没有任何反应,并且DataSource日志中没有提到连接表:
array(
'log' => array(
(int) 0 => array(
'query' => 'BEGIN',
'params' => array(),
'affected' => null,
'numRows' => null,
'took' => null
),
(int) 1 => array(
'query' => 'INSERT INTO `xray2`.`users` (`username`) VALUES ('test06apd')',
'params' => array(),
'affected' => (int) 1,
'numRows' => (int) 1,
'took' => (float) 1
),
(int) 2 => array(
'query' => 'COMMIT',
'params' => array(),
'affected' => (int) 1,
'numRows' => (int) 1,
'took' => (float) 1
)
),
'count' => (int) 3,
'time' => (float) 2
)
我是否遗漏了一些非常明显的东西,或者是否有一些我尚未发现的蛋糕怪癖?
答案 0 :(得分:1)
您只是告诉Cake保存主要模型数据。您需要更改此行: -
$saved = $this->User->save($data, array('deep' => true));
要: -
$saved = $this->User->saveAssociated($data, array('deep' => true));
saveAssociated()
告诉Cake保存当前模型及其相关数据。您也不需要传递array('deep' => true)
,因为您只将数据保存到直接关联的模型。所以使用它会更好(也更安全): -
$saved = $this->User->saveAssociated($data);
<强>更新强>
由于您没有使用关联中为数据定义的别名,因此保存数据存在问题。因此,当Cake尝试保存关联数据时,它无法看到任何数据。根据您的代码,您的User
模型拥有并属于许多Courses
(复数),但您的保存数据使用Course
(单数)。因此,您的表格应为: -
echo $this->Form->input('Courses.Courses', array(
'error' => false,
'required' => true
));
应该注意Cake naming conventions使用单数形式的模型名称,因此最好在关联中使用Course
而不是Courses
。如果您更改此设置,则您的关联可以简化为以下内容: -
public $hasAndBelongsToMany = array(
'Course'
);
Cake将了解如何处理连接表和外键,因为它们符合命名约定。然后你不需要改变你的表格。