- Moon.Wong
- 评论(0)
如何在一对多关系中保存相关模型的数据。
关联(Associations)让保存相关数据变得极其简单。我们接下来会创建一个简单的程序,该程序可以保存图书的信息,并在保存的同时将它与作者联系起来。我们将在先前代码的基础上添加一个一些的代码,以便将保存功能添加进来。
动手时间:保存相关模型中的数据
1,在BookController中(文件位置:/app/controllers/books_controller.php),添加表单助手(FormHelper)以及一个新操作add():
class BooksController extends AppController {
var $name = 'Books';
var $helpers = array('Form' );
function index() {
$this->Book->recursive = 1;
$books = $this->Book->find('all',
array('fields' =>
array('Book.isbn','Book.title','Author.name')
)
);
$this->set('books', $books);
}
function add() {
if (!empty($this->data)) {
$this->Book->create();
$this->Book->save($this->data);
$this->redirect(array('action'=>'index'));
}
$authors = $this->Book->Author->generateList();
$this->set('authors', $authors);
}
}
?>
2,为操作'/books/add' 添加一个视图(文件位置:/app/views/books/add.ctp)
<?php echo $form->create('Book');?>
<fieldset>
<legend>Add New Book</legend>
<?php
echo $form->input('isbn');
echo $form->input('title');
echo $form->input('description');
echo $form->input('author_id');
?>
</fieldset>
<?php echo $form->end('Submit');?>
3,将浏览器指向下面这个地址,并添加一个图书。
http://localhost/relationship/books/add
怎么回事?
在BooksController的add()操作中,我们首先检查视图是否有表单数据发送过来。当视图没有发送表单数据时,浏览器会显示一个表单以接受用户输入。表单中有一个文本输入框以接收图书的信息。另外,我们也有一个选择列表可以选择相关的作者。这个选择列表包含 了所有的作者。我们可以从其中选择一个作者。CakePHP模型的函数 generateList() 在这里是用来创建这个选择列表的。
Author->generateList() 会返回是一个数组,其中有作者id=>姓名这种键值对,具体形式如下:
Array
(
[1] => Author 1
[2] => Author 2
[3] => ...
)
| [ |
在一个模型内容,所有与该模型相关的模型类都是可以访问。像我们可以在Book模型中以Book->Author的形式访问Author模型,反之亦然。 |
这个函数对于创建HTML的Select标签非常好用。我们通过$authors变量将 Book->Author->generateList() 函数的返回结果传送给了视图。在视图文件中,我们使用了表单助手的input方法,$form->input('author_id')。这个 input方法会聪明地位每个作者创建一个select标签,其中标签的label名为作者姓名,id为标签的 值。$form->input('author_id')输出内容类似下面:
<select>
<option value="1">Author 1</option>
<option value="2">Author 2</option>
<option value="3">Author 3</option>
...
</select>
我们将在 第七章对这个“便捷智能的”表单助手深入选析,当提交表单的按钮被地监视,所有表单数据被发送会BooksController的add操作。然后这些表 单数据被传送给Book->save函数,将book的数据保存进数据库,并自动将新添加的书与所选作者关联起来(将所选作者的id保存在book 表中的author_id字段中)。当保存操作完成后,控制器会转跳到index操作。我们可以在index的图书列表中看到新添加的书。
generateList() 函数的样式是下面这样:
generateList(string $conditions, string $order, int $limit, string $keyPath, string $valuePath)
$conditions, $order, 和 $limit参数与我们在find函数中所用到一样。 generateList()函数默认是将id和模型的name字段以键值对的形式保存返回数组中。我们可以通过设置 $keyPath和$valuePath参数改变默设置
如果我们想得到一个数组,它其中的键值对是前十位作者的id以及作者模型的last_name字段,它是按照last_name字段来排序,我们可以使用 $order, $limit, $keyPath, 和 $valuePath 参数,像下面这样:
$this->Author->generateList(
null,
'last_name ASC',
10,
'{n}.Author.initial',
'{n}.Author.last_name'
);