MongoDB的擴展的Yii 2 does not provide any special way to work with embedded documents (sub-documents)。要做到這一點,你需要首先處理自定義驗證。你可以試試下面的辦法:一般模式是,首先建立一個custom validator,說\ COMMON \ \驗證EmbedDocValidator.php
namespace common\validators;
use yii\validators\Validator;
class EmbedDocValidator extends Validator
{
public $scenario;
public $model;
/**
* Validates a single attribute.
* Child classes must implement this method to provide the actual validation logic.
*
* @param \yii\mongodb\ActiveRecord $object the data object to be validated
* @param string $attribute the name of the attribute to be validated.
*/
public function validateAttribute($object, $attribute)
{
$attr = $object->{$attribute};
if (is_array($attr)) {
$model = new $this->model;
if($this->scenario){
$model->scenario = $this->scenario;
}
$model->attributes = $attr;
if (!$model->validate()) {
foreach ($model->getErrors() as $errorAttr) {
foreach ($errorAttr as $value) {
$this->addError($object, $attribute, $value);
}
}
}
} else {
$this->addError($object, $attribute, 'should be an array');
}
}
}
和模型嵌入的文檔\ COMMON \型號\ Preferences.php
namespace common\models;
use yii\base\Model;
class Preferences extends Model
{
/**
* @var string $lang
*/
public $lang;
/**
* @var string $currency
*/
public $currency;
public function rules()
{
return [
[['lang', 'currency'], 'required'],
];
}
}
而在頂級機型 在共同\型號setup the validator \ user.php的:
public function rules()
{
return [
[['preferences', 'name'], 'required'],
['preferences', 'common\validators\EmbedDocValidator', 'scenario' => 'user','model'=>'\common\models\Preferences'],
];
}
的general recommendation是avoiding use of embedded documents在文檔的頂部水平移動它們的屬性。例如:代替
{
name: 'Bob',
surnames: {
'first': 'Foo',
'second': 'Bar'
},
age: 27,
preferences: {
lang: 'en',
currency: 'EUR'
}
}
使用以下結構:
{
name: 'Bob',
surnames_first: 'Foo',
surnames_second: 'Bar'
age: 27,
preferences_lang: 'en',
preferences_currency: 'EUR'
}
,然後可以通過延伸YII \ mongodb的\ ActiveRecord的聲明作爲ActiveRecord
類並實現collectionName
和'attributes'
方法:
use yii\mongodb\ActiveRecord;
class User extends ActiveRecord
{
/**
* @return string the name of the index associated with this ActiveRecord class.
*/
public static function collectionName()
{
return 'user';
}
/**
* @return array list of attribute names.
*/
public function attributes()
{
return ['_id', 'name', 'surnames_first', 'surnames_second', 'age', 'preferences_lang', 'preferences_currency'];
}
}
對不起,在這裏回覆。既然你的回答是我在這個問題上與Yii開發者聯繫的,那麼讓我們來看看這會促使我們:https://github.com/yiisoft/yii2/issues/4899 – alexandernst 2015-04-08 16:35:36