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