— 文章所属小组: CakePHP
CakePHP应用开发 第六章 对象关系映射(ORM):构建表关系 (4)
  • 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'
);

填写登录信息
用户名
密码