Chinaunix首页 | 论坛 | 博客
  • 博客访问: 963611
  • 博文数量: 335
  • 博客积分: 10287
  • 博客等级: 上将
  • 技术积分: 3300
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-08 15:29
文章分类

全部博文(335)

文章存档

2015年(4)

2014年(15)

2013年(17)

2012年(11)

2011年(12)

2010年(96)

2009年(27)

2008年(34)

2007年(43)

2006年(39)

2005年(37)

我的朋友

分类:

2007-09-14 16:11:36

保存 hasAndBelongsToMany 关系

保存hasOne, belongsTo, 以及hasMany的关联model是非常简单的:你仅需要将外键设置为关联modelID。一旦完成,你也仅需要调用modelsave()方法,这样所有的东东都会正确的关联了。

但是对于hasAndBelongsToMany,就有点晦涩了,但是我们已经特意让它尽可能简单。继续我们的例子,我们需要一些表单,这些表单将Tag关联到Post。现在让我们创建一个表单,此表单创建post,以及将他们和一个存在的tag列表关联。

事实上,你可能喜欢创建一个表单来创建新的tag,并将他们在空中关联-但是出于简单,我们仅需要为你说明如何将他们关联,并让你得到它。

Cake中,当你正保存它自己的modeltag名(如果你在使用HTML helper)应该是'Model/field_name'.让我们从创建post的表单部分开始吧:

创建post/app/views/posts/add.thtml 表单

<h1>Write a New Posth1>

  <table>  

      <tr>   

         <td>Title:td> 

         <td>php echo  html->input('Post/title')?>td>

      tr>

      <tr>       

         <td>Body:<td>

         <td>php echo $html->textarea('Post/title')?>td>

     tr>

     <tr>

        <td colspan="2">

        php echo $html->hidden('Post/user_id', array('value'=>$this->controller->Session->read('User.id')))?>

        php echo $html->hidden('Post/status' , array('value'=>'0'))?>

        php echo $html->submit('Save Post')?>

        td>

       tr>

 table>

当前用的表单仅创建Post记录。让我们增加一些代码使你将给定的Post绑定到一个或多个Tag

/app/views/posts/add.thtml (增加的Tag 关联代码)

<h1>Write a New Posth1>

    <table>

        <tr>

            <td>Title:td>

            <td>php echo $html->input('Post/title')?>td>

        tr>

        <tr>

            <td>Body:td>

            <td>php echo $html->textarea('Post/title')?>td>

        tr>

       

        <tr>

            <td>Related Tags:td>

            <td>php echo $html->selectTag('Tag/Tag', $tags, null, array('multiple' => 'multiple')) ?>

            td>

        tr>

       

        <tr>

            <td colspan="2">

                php echo $html->hidden('Post/user_id', array('value'=>$this->controller->Session->read('User.id')))?>

                php echo $html->hidden('Post/status' , array('value'=>'0'))?>

                php echo $html->submit('Save Post')?>

            td>

        tr>

table>

对于一个调用,为了让controller$this->Post->save()保存新Post和它关联的Tag之间的联系,字段名必须是"Tag/Tag"形式(已显示的名字属性看起来是'data[ModelName][ModelName][]'),已提交的数据必须为一个ID,或者关联记录的ID数组。因为我们在这里正使用多个选择,所以提交的Tag/Tag数据应该为ID数组。

这里的$tags变量仅是一个数组,里面的键是可能的TagID,值为多选元素里的显示的Tag名。

使用bindModel() unbindModel()在空中改变关联

当创建应用程序时,你偶尔可能希望为一些特别的情况改变model关联信息。如果model文件里的关联设置给你太多(或不够)信息,你可以使用2model函数为下一次的查找绑定和解除绑定关联。

让我们建立一些model,以至我们可以看看bindModel()unbindModel()是如何工作的。我们将从2model开始:

leader.php follower.php

 

class Leader extends AppModel

{

    var $name = 'Leader';

 

    var $hasMany = array(

        'Follower' => array(

            'className' => 'Follower',

            'order'     => 'Follower.rank'

        )

    );

}

 

?>

 

 

class Follower extends AppModel

{

    var $name = 'Follower';

}

 

?>

现在,在LeadersController中,我们可以使用Leader Model中的find()方法准备一个Leader以及它的关联Follower。从上面可以看到,Leader model的关联数组定义了一个"Leader hasMany Followers"的关系。出于描述的目的,让我们使用unbindModel()去除那个关联中间controller

leaders_controller.php (部分)

function someAction()

{

    //This fetches Leaders, and their associated Followers

    $this->Leader->findAll();

 

    //Let's remove the hasMany...

    $this->Leader->unbindModel(array('hasMany' => array('Follower')));

   

    //Now a using a find function will return Leaders, with no Followers

    $this->Leader->findAll();

 

    //NOTE: unbindModel only affects the very next find function.

    //An additional find call will use the configured association information.

 

    //We've already used findAll() after unbindModel(), so this will fetch

    //Leaders with associated Followers once again...

    $this->Leader->findAll();

}

unbindModel()函数对其他关联类似:仅需要改变关联类型名以及model 类名。unbindModel()的基本使用方法如下:

普通的 unbindModel() 实例

$this->Model->unbindModel(array('associationType' => array('associatedModelClassName')));

既然我们成功移除了空中的一个关联,还是让我们增加一个吧。还没有PrincipleLeader需要一些关联的Principle。我们的Principle model的文件还不太丰富,除了$name变量语句。让我们把这些Principle关联到Leader吧(而且为了跟踪查找函数哟):

leaders_controller.php (部分)

funciton anotherAction()

{

    //There is no Leader hasMany Principles in the leader.php model file, so

    //a find here, only fetches Leaders.

    $this->Leader->findAll();

 

    //Let's use bindModel() to add a new association to the Principle model:

    $this->Leader->bindModel(

        array('hasMany' => array(

                'Principle' => array(

                    'className' => 'Principle'

                )

            )

        )

    );

 

    //Now that we're associated correctly, we can use a single find function

    //to fetch Leaders with their associated principles:

    $this->Leader->findAll();

}

bindModel()函数可以便于创建一个新的关联,但是如果你想改变给定关联的排列顺序或则其他参数,它也会有用。

你已经有了它。bindModel的基本使用是封装一个普通的关联数组,在此数组里,它的键会在你试图创建的关联后命名:

普通 bindModel() 实例

$this->Model->bindModel(

        array('associationName' => array(

                'associatedModelClassName' => array(

                    // normal association keys go here...

                )

            )

        )

    );

请注意,你的表需要正确的键(或者正确配置的关联数组)来绑定model



[1] 需要说明的是,并不是所有的数据库都支持事务,所以使用此功能时,数据库必须支持事务。

阅读(1237) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~