阿江 2017-10-01 15:53:59 2156次浏览 0条回复 1 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#saving-relations
11、Saving Relations(存储关联属性)

本文主题:AR存储关联属性(Saving Relations)

11、存储关联属性(Saving Relations) 当使用关联数据时,你经常需要在不同数据之间建立或删除关联关系,这就需要为关联字段设置合适的值,使用AR,你就不用书写如下代码了:

$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
// ...
// setting the attribute that defines the "customer" relation in Order
$order->customer_id = $customer->id;
$order->save();

AR提供了link()方法让你可以更漂亮的完成上述任务:

$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
// ...
$order->link('customer', $customer);

link()方法需要你定义关联名,并指定将要建立关联的Active Record实例。此方法将会修改连接两个AR实例的属性值,并将它们存储到数据库中,在上例中,将会设置Order对象的customer_id属性值为Customer对象的id,并将它存储到数据库中。

存储关联属性
文件位置:
D:\phpwork\basic\models\ArticleInfo.php
源代码:
    public function getAuthor()
    {
        return $this->hasOne(AuthorInfo::className(), ['_id' => 'authId']);
    }
文件位置:
D:\phpwork\basic\controllers\AuthorController.php
源代码:
		$author=AuthorInfo::findOne(['_id'=>'58a14587e4017a1c1600002a']);
		$article=ArticleInfo::findOne(['_id'=>'58a14707e4017aa01a000029']);
		$article->title='15689';//会对$article进行修改
		$article->link('author',$author);
		//连接后,id=58a14707e4017aa01a000029的ArticleInfo,其authId属性将变更为'58a14587e4017a1c1600002a'
		//$article->link()自动调用$article->save(false)方法,所有$article的修改都会被保存,但不进行数据验证!
		echo 'same OK22';
测试结果:
/*
same OK22
*/
取消关联属性,unlink()
源代码:
		$author=AuthorInfo::findOne(['_id'=>'58a14587e4017a1c1600002a']);
		$article=ArticleInfo::findOne(['_id'=>'58a14707e4017aa01a000029']);
		$article->title='15689aa';//会对$article进行修改
		$article->unlink('author',$author);
//		$article->unlink('author',$author,true);//将会删除整条$article记录,不能使用后面这个true参数
		echo 'same OK22';
//会将"authId"设置为null
测试结果:
/*
{
    "_id" : ObjectId("58a14707e4017aa01a000029"),
    "createInfo" : {
        "time" : 1486964487,
        "ip" : "::1"
    },
    "isDeleted" : false,
    "authInfo" : {
        "id" : ObjectId("58a14587e4017a1c1600002a"),
        "name" : "abc",
        "level" : "18"
    },
    "title" : "15689aa",
    "content" : "Are you OK?Content",
    "updateInfo" : {
        "time" : 1489126994,
        "ip" : "::1"
    },
    "level" : 123,
    "click" : 25,
    "authId" : null
}
*/

注意:你不能连接两个新创建的AR实例。

当一个关联属性是通过Junction表定义时,使用link()的好处更加明显。例如,你可以使用以下代码去连接Order和Item实例: $order->link('items',$item); 上述代码会自动插入关联order和item实例的一条记录到order_item表中去。

信息:当存储相关AR实例时,link()方法不会执行任何数据验证,你需要在调用此方法前验证输入的数据。

存储Junction表关联属性实例,link()
文件位置:
D:\phpwork\basic\controllers\AuthorController.php
源代码:
		$tag=Tags::findOne(['_id'=>'58b928cae4017a8c0c000029']);
		$article=ArticleInfo::findOne(['_id'=>'58a14707e4017aa01a000029']);
		$article->title='15689';//不会对$article进行修改,因为allTags操作的是article_tag表
		$article->link('allTags',$tag);
		echo 'same OK22';
文件位置:
D:\phpwork\basic\models\ArticleInfo.php
源代码:
    public function getAllTags(){
        return $this->hasMany(Tags::className(), ['_id' => 'tagId'])
            ->select(['tag'])
            ->asArray()
            //使用via()
            ->via('articleTags');
    }

//在表article_tag中创建的新记录,link()不会检测是否已有重复的关联记录,会不断的重复插入!

测试结果:
/*
{
    "_id" : ObjectId("58c241bbe4017a780c000029"),
    "articleId" : ObjectId("58a14707e4017aa01a000029"),
    "tagId" : ObjectId("58b928cae4017a8c0c000029")
}
*/

// 存储Junction表关联属性实例,unlink() link()相反的操作是unlink(),它将取消两个AR实例之间的连接,例如:

$customer = Customer::find()->with('orders')->where(['id' => 123])->one();
$customer->unlink('orders', $customer->orders[0]);

默认情况下,unlink()方法将设置定义关联关系的外键值为null,你可以传一个为true的$delete 参数用于删除包含外键的表记录。 当一个Junction表被包含在一个关联中,调用unlink()会将Junction表中的外键被清空,或者当$delete 是true时,含有外键的相应行将会被删除。

文件位置:
D:\phpwork\basic\controllers\AuthorController.php
源代码:

		$tag=Tags::findOne(['_id'=>'58b928cae4017a8c0c000029']);
		$article=ArticleInfo::findOne(['_id'=>'58a14707e4017aa01a000029']);
		$article->title='15689';//不会对$article进行修改,因为allTags操作的是article_tag表
		$article->unlink('allTags',$tag);//仅将外键值设为null
//		$article->unlink('allTags',$tag,true);//会将article_tag表中的记录删除
		echo 'same OK22';
文件位置:
D:\phpwork\basic\models\ArticleInfo.php
源代码:
    public function getAllTags(){
        return $this->hasMany(Tags::className(), ['_id' => 'tagId'])
            ->select(['tag'])
            ->asArray()
            //使用via()
            ->via('articleTags');
    }
测试结果:
/*unlink()不会删除article_tag表中的关联记录,仅会将所有符合条件的记录值设为null,如下:
{
    "_id" : ObjectId("58bf9939e4017a7c0c00002a"),
    "tagId" : null,
    "articleId" : null
}
*/

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册