notamedia / yii2-relation
在 Yii2 中保存相关数据
1.0.0
2017-08-24 14:16 UTC
Requires
- php: >=5.6.0
- yiisoft/yii2: ~2.0
Requires (Dev)
- codeception/codeception: ^2.3
- codeception/specify: ^0.4.3
- codeception/verify: ^0.3.2
- yiisoft/yii2-codeception: ^2.0.5
This package is auto-updated.
Last update: 2024-09-19 20:53:49 UTC
README
支持关系数据管理的行为。
- 从 POST 数组中插入相关模型。
- 通过回调函数对新模型进行预处理。
- 从数据库中删除不存在于 POST 数组中的相关模型。
- 跳过在数据库中已存在且具有相同属性的关联模型。
- 如果关系模型保存/删除发生错误,则回滚数据库更改。
- 支持一对一和一对多关系。
通过预处理,您可以在创建相关模型之前设置额外的逻辑。例如,在多对多关系中向连接表中添加额外的列数据。
此行为使用所有者模型中关系属性的获取器,这些获取器必须返回 ActiveQuery
对象。如果您在 ActiveQuery
对象的 ON 条件中使用字符串值,则此行为将抛出异常。
安装
composer require notamedia/yii2-relation
用法
要使此行为工作,您需要
- 将所有关联属性添加到规则中作为安全属性。
- 声明关系属性的获取器。
- 将属性或带有回调的属性放入行为的关系属性中。
- 所有使用的模型都需要只有一个主键列。
一对一关系
<?php class News extends \yii\db\ActiveRecord { public function rules() { return [ [['file'], 'safe'] ]; } public function getFile() { return $this->hasOne(File::class, ['id' => 'file_id']); } public function behaviors() { return [ [ 'class' => \notamedia\relation\RelationBehavior::class, 'relations' => ['file'] ] ]; } public function transactions() { return [ $this->getScenario() => static::OP_ALL ]; } }
一对多关系
<?php class News extends \yii\db\ActiveRecord { public function rules() { return [ [['images'], 'safe'] ]; } public function getImages() { return $this->hasMany(Image::class, ['news_id' => 'id']); } public function behaviors() { return [ [ 'class' => \notamedia\relation\RelationBehavior::class, 'relations' => ['images'] ] ]; } public function transactions() { return [ $this->getScenario() => static::OP_ALL ]; } }
多对多关系
使用 via
<?php class News extends \yii\db\ActiveRecord { public function rules() { return [ [['categories'], 'safe'] ]; } public function getNewsHasCategories() { return $this->hasMany(NewsHasCategory::class, ['news_id' => 'id']); } public function getCategories() { return $this->hasMany(Category::class, ['id' => 'category_id']) ->via('newsHasCategories'); } public function behaviors() { return [ [ 'class' => \notamedia\relation\RelationBehavior::class, 'relations' => ['categories'] ] ]; } public function transactions() { return [ $this->getScenario() => static::OP_ALL ]; } }
使用 viaTable
<?php class News extends \yii\db\ActiveRecord { public function rules() { return [ [['categories', 'categories_type_archive'], 'safe'] ]; } public function getCategories() { return $this->hasMany(Category::class, ['id' => 'category_id']) ->viaTable('news_has_categories', ['news_id' => 'id']); } // with onCondition public function getCategories_type_archive() { return $this->hasMany(Category::class, ['id' => 'category_id']) ->viaTable('news_has_categories', ['news_id' => 'id'], function($query) { return $query->onCondition(['type' => 'archive']); }); } public function behaviors() { return [ [ 'class' => \notamedia\relation\RelationBehavior::class, 'relations' => ['categories', 'categories_type_archive'] ] ]; } public function transactions() { return [ $this->getScenario() => static::OP_ALL ]; } }
排序数据关系
<?php class News extends \yii\db\ActiveRecord { public function rules() { return [ [['categories'], 'safe'] ]; } public function getNewsHasCategories() { return $this->hasMany(NewsHasCategory::class, ['news_id' => 'id']); } public function getCategories() { return $this->hasMany(Category::class, ['id' => 'category_id']) ->via('newsHasCategories'); } public function behaviors() { $sortIndex = 1; return [ [ 'class' => \notamedia\relation\RelationBehavior::class, 'relations' => [ 'categories' => function (NewsHasCategory $model) use (&$sortIndex) { $model->sort = $sortIndex++; return $model; } ] ] ]; } public function transactions() { return [ $this->getScenario() => static::OP_ALL ]; } }