[Yii2笔记]015 AR存储关联属性(Saving Relations) [ 技术分享 ]
说明
学习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
}
*/
(全文完)
共 0 条回复
没有找到数据。
阿江
注册时间:2015-10-18
最后登录:2024-03-03
在线时长:186小时21分
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276