validation - Yii "required"验证失败 : $model->attributes returns correct data, 但 $model->requiredAttribute 为空?

标签 validation activerecord yii

我有一个扩展 CActiveRecord 的模型,其具有以下内容 rules()方法:

/**
 * @return array validation rules for model attributes.
 */
public function rules()
{
    return array(
        array('name, locationId', 'required'),
        array('locationId', 'numerical', 'integerOnly'=>true),
        array('name', 'length', 'max'=>1024),
        array('name', 'safe'),
        // The following rule is used by search().
        // Please remove those attributes that should not be searched.
        array('id, name, description, locationId', 'safe', 'on'=>'search'),
    );
}

这是 actionCreate()相应 Controller 中的方法:

public function actionCreate()
{
    $model = new Destination;

    if ( isset($_POST['Destination']) )
    {
      $model->attributes = $_POST['Destination'];

      // logging statement!
      Yii::log("Name: {$model->name}\nLocationID: {$model->locationId}\nAll attribs:\n".CVarDumper::dumpAsString($model->attributes), 'warning', 'application.controllers.DestinationController.actionCreate');

      if ( $model->save() )
        $this->redirect(array('view', 'id'=>$model->id));
    }

    $this->render( 'create', array (
        'model' => $model,
    ));
}

不幸的是,每次我尝试使用此操作创建新记录时,都会收到错误 namelocationId不能为空,即使它们已在表单中设置。 actionCreate() 中的日志记录语句的输出,上面看起来像这样:

2012/08/14 18:04:51 [warning]     [application.controllers.DestinationController.actionCreate] Name:
LocationID:
All attribs:
array
(
    'name' => 'Test Name'
    'description' => 'Test Description'
    'locationId' => '93'
    'contactId' => ''
    'accessId' => ''
    'fullDistance' => ''
)

如您所见,倾销 $model->attributes显示正确的数据,但尝试获取单个属性(例如调用 $model->name$model->locationId )不会返回任何内容。我通过save()追踪到了这一点, validate()等调用,看起来这导致了 required name 的规则和locationId失败。

有什么想法吗?

编辑:附加日志信息

    2012/08/15 16:58:03 [info] [application] Model:
Destination#1
(
    [CActiveRecord:_md] => CActiveRecordMetaData#2
    (
        [tableSchema] => CMysqlTableSchema#3
        (
            [schemaName] => null
            [name] => 'destination'
            [rawName] => '`destination`'
            [primaryKey] => 'id'
            [sequenceName] => ''
            [foreignKeys] => array
            (
                'accessId' => array
                (
                    '0' => 'access'
                    '1' => 'id'
                )
                'contactId' => array
                (
                    '0' => 'contact'
                    '1' => 'id'
                )
                'locationId' => array
                (
                    '0' => 'location'
                    '1' => 'id'
                )
            )
            [columns] => array
            (
                'id' => CMysqlColumnSchema#4
                (
                    [name] => 'id'
                    [rawName] => '`id`'
                    [allowNull] => false
                    [dbType] => 'int(11)'
                    [type] => 'integer'
                    [defaultValue] => null
                    [size] => 11
                    [precision] => 11
                    [scale] => null
                    [isPrimaryKey] => true
                    [isForeignKey] => false
                    [autoIncrement] => true
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'name' => CMysqlColumnSchema#5
                (
                    [name] => 'name'
                    [rawName] => '`name`'
                    [allowNull] => false
                    [dbType] => 'varchar(1024)'
                    [type] => 'string'
                    [defaultValue] => null
                    [size] => 1024
                    [precision] => 1024
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => false
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'description' => CMysqlColumnSchema#6
                (
                    [name] => 'description'
                    [rawName] => '`description`'
                    [allowNull] => true
                    [dbType] => 'text'
                    [type] => 'string'
                    [defaultValue] => null
                    [size] => null
                    [precision] => null
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => false
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'locationId' => CMysqlColumnSchema#7
                (
                    [name] => 'locationId'
                    [rawName] => '`locationId`'
                    [allowNull] => false
                    [dbType] => 'int(11)'
                    [type] => 'integer'
                    [defaultValue] => null
                    [size] => 11
                    [precision] => 11
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => true
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'contactId' => CMysqlColumnSchema#8
                (
                    [name] => 'contactId'
                    [rawName] => '`contactId`'
                    [allowNull] => true
                    [dbType] => 'int(11)'
                    [type] => 'integer'
                    [defaultValue] => null
                    [size] => 11
                    [precision] => 11
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => true
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'accessId' => CMysqlColumnSchema#9
                (
                    [name] => 'accessId'
                    [rawName] => '`accessId`'
                    [allowNull] => true
                    [dbType] => 'int(11)'
                    [type] => 'integer'
                    [defaultValue] => null
                    [size] => 11
                    [precision] => 11
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => true
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
                'fullDistance' => CMysqlColumnSchema#10
                (
                    [name] => 'fullDistance'
                    [rawName] => '`fullDistance`'
                    [allowNull] => true
                    [dbType] => 'int(11)'
                    [type] => 'integer'
                    [defaultValue] => null
                    [size] => 11
                    [precision] => 11
                    [scale] => null
                    [isPrimaryKey] => false
                    [isForeignKey] => false
                    [autoIncrement] => false
                    [CComponent:_e] => null
                    [CComponent:_m] => null
                )
            )
            [CComponent:_e] => null
            [CComponent:_m] => null
        )
        [columns] => array
        (
            'id' => CMysqlColumnSchema#4(...)
            'name' => CMysqlColumnSchema#5(...)
            'description' => CMysqlColumnSchema#6(...)
            'locationId' => CMysqlColumnSchema#7(...)
            'contactId' => CMysqlColumnSchema#8(...)
            'accessId' => CMysqlColumnSchema#9(...)
            'fullDistance' => CMysqlColumnSchema#10(...)
        )
        [relations] => array
        (
            'location' => CBelongsToRelation#11
            (
                [joinType] => 'LEFT OUTER JOIN'
                [on] => ''
                [alias] => null
                [with] => array()
                [together] => null
                [scopes] => null
                [name] => 'location'
                [className] => 'Location'
                [foreignKey] => 'locationId'
                [select] => '*'
                [condition] => ''
                [params] => array()
                [group] => ''
                [join] => ''
                [having] => ''
                [order] => ''
                [CComponent:_e] => null
                [CComponent:_m] => null
            )
            'activities' => CManyManyRelation#12
            (
                [limit] => -1
                [offset] => -1
                [index] => null
                [through] => null
                [joinType] => 'LEFT OUTER JOIN'
                [on] => ''
                [alias] => null
                [with] => array()
                [together] => null
                [scopes] => null
                [name] => 'activities'
                [className] => 'Activity'
                [foreignKey] => 'destinationHasActivity(destinationId, activityId)'
                [select] => '*'
                [condition] => ''
                [params] => array()
                [group] => ''
                [join] => ''
                [having] => ''
                [order] => ''
                [CComponent:_e] => null
                [CComponent:_m] => null
            )
            'attributes' => CManyManyRelation#13
            (
                [limit] => -1
                [offset] => -1
                [index] => null
                [through] => null
                [joinType] => 'LEFT OUTER JOIN'
                [on] => ''
                [alias] => null
                [with] => array()
                [together] => null
                [scopes] => null
                [name] => 'attributes'
                [className] => 'Attribute'
                [foreignKey] => 'destinationHasAttribute(destinationId, attributeId)'
                [select] => '*'
                [condition] => ''
                [params] => array()
                [group] => ''
                [join] => ''
                [having] => ''
                [order] => ''
                [CComponent:_e] => null
                [CComponent:_m] => null
            )
            'surfaces' => CManyManyRelation#14
            (
                [limit] => -1
                [offset] => -1
                [index] => null
                [through] => null
                [joinType] => 'LEFT OUTER JOIN'
                [on] => ''
                [alias] => null
                [with] => array()
                [together] => null
                [scopes] => null
                [name] => 'surfaces'
                [className] => 'Surface'
                [foreignKey] => 'destinationHasSurface(destinationId, surfaceId)'
                [select] => '*'
                [condition] => ''
                [params] => array()
                [group] => ''
                [join] => ''
                [having] => ''
                [order] => ''
                [CComponent:_e] => null
                [CComponent:_m] => null
            )
            'images' => CManyManyRelation#15
            (
                [limit] => -1
                [offset] => -1
                [index] => null
                [through] => null
                [joinType] => 'LEFT OUTER JOIN'
                [on] => ''
                [alias] => null
                [with] => array()
                [together] => null
                [scopes] => null
                [name] => 'images'
                [className] => 'Image'
                [foreignKey] => 'destinationHasImage(destinationId, imageId)'
                [select] => '*'
                [condition] => ''
                [params] => array()
                [group] => ''
                [join] => ''
                [having] => ''
                [order] => ''
                [CComponent:_e] => null
                [CComponent:_m] => null
            )
        )
        [attributeDefaults] => array()
        [CActiveRecordMetaData:_model] => Destination#16
        (
            [CActiveRecord:_md] => CActiveRecordMetaData#2(...)
            [CActiveRecord:_new] => false
            [CActiveRecord:_attributes] => array()
            [CActiveRecord:_related] => array()
            [CActiveRecord:_c] => null
            [CActiveRecord:_pk] => null
            [CActiveRecord:_alias] => 't'
            [CModel:_errors] => array()
            [CModel:_validators] => null
            [CModel:_scenario] => ''
            [CComponent:_e] => null
            [CComponent:_m] => null
        )
    )
    [CActiveRecord:_new] => true
    [CActiveRecord:_attributes] => array()
    [CActiveRecord:_related] => array
    (
        'attributes' => array
        (
            'name' => 'Test name'
            'description' => ''
            'contactId' => ''
            'fullDistance' => ''
        )
    )
    [CActiveRecord:_c] => null
    [CActiveRecord:_pk] => null
    [CActiveRecord:_alias] => 't'
    [CModel:_errors] => array()
    [CModel:_validators] => null
    [CModel:_scenario] => 'insert'
    [CComponent:_e] => null
    [CComponent:_m] => null
)

安全属性:

2012/08/15 16:58:03 [info] [application] Safe attributes:
array
(
    '0' => 'name'
    '1' => 'locationId'
    '2' => 'fullDistance'
    '3' => 'description'
)

最佳答案

这是一次命名冲突。该数据库中有一个“属性”表,以及引用该表的关系 $model->attributes。 Yii 生成的代码在这一行进行大量赋值:

$model->attributes = $_POST['Destination'];

由于 $model->attributes 已被重新定义为关系,因此大量赋值无法正确执行。

关于validation - Yii "required"验证失败 : $model->attributes returns correct data, 但 $model->requiredAttribute 为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11962930/

相关文章:

c# - 有没有办法在 ASP.NET/C# 中不加载特定控件?

javascript - Jquery 验证多个条件

c# - 呈现 xml 验证错误

javascript - 如何在 Ionic 3 和 Angular 4 中禁用表单验证?

ruby-on-rails - 你如何在 Rails 中按一天中的时间过滤记录?

sql - 尽管有缓存,搜索查询的性能还是被共同好友限制了 98%

php - 在 Yii 中获取当前 Controller 和 Action ID

php - yii - 如何在模块中对小部件进行主题化

php - Yii - 结果集中没有列

ruby-on-rails - 当 :allow_destroy => true 时删除关联而不是销毁对象