doujianmin6527 2013-12-16 10:38
浏览 39
已采纳

Yii crud更新 - 错误400 - 复合键导致问题

I am having a problem with the UPDATE of the 'bootstrap.widgets.TbGridView' in YII php framework.

The link generated by the UPDATE/pencil icon of my 'bootstrap.widgets.TbGridView' produce an Error 400. The link looks like this

http://mysite/index.php?r=marketingchannel/update&id%5Bid%5D=119&id%5BControllingChannel_id%5D=7

I have tried entering the link manually like this

http://mysite/index.php?r=marketingchannel/update&id=119&ControllingChannel_id=7

then I get the following CDbException

The value for the column "id" is not supplied when querying the table "marketingchannel".

The Stacktrace (of my entering link manually) looks like this:

0. /framework/db/schema/CDbCommandBuilder.php(519): CDbCommandBuilder->createInCondition(CMysqlTableSchema, array("id", "ControllingChannel_id"), array("119"), "t.")
1. /framework/db/ar/CActiveRecord.php(1431): CDbCommandBuilder->createPkCriteria(CMysqlTableSchema, "119", "", array(), ...)
2. /protected/controllers/MarketingchannelController.php(158): CActiveRecord->findByPk("119")
3. /protected/controllers/MarketingchannelController.php(89): MarketingchannelController->loadModel("119")
4. unknown(0): MarketingchannelController->actionUpdate("119")
5. /framework/web/actions/CAction.php(108): ReflectionMethod->invokeArgs(MarketingchannelController, array("119"))
6. /framework/web/actions/CInlineAction.php(47): CAction->runWithParamsInternal(MarketingchannelController, ReflectionMethod, array("r" => "marketingchannel/update", "id" => "119", "ControllingChannel_id" => "7"))
7. /framework/web/CController.php(308): CInlineAction->runWithParams(array("r" => "marketingchannel/update", "id" => "119", "ControllingChannel_id" => "7"))

This tells me it is finding the id in the url...however cannot process it.

Note: I realise the Gridview is producing a link with [ ] parenthese url encoded. However I dont understand why even when I manually enter a link, it still doesnt work.

Note2: I have many Gridviews like this in my application, it is only two that are not working. Coincidently their models are related by Foreign Keys. However other Gridviews related to these two, do function properly.

Update: Code of my Controller's Update Action

/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
$model=$this->loadModel($id);

// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);

if(isset($_POST['Marketingchannel']))
{
$model->attributes=$_POST['Marketingchannel'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}

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

Update: Code of my Model

/**
 * This is the model class for table "marketingchannel".
 *
 * The followings are the available columns in table 'marketingchannel':
 * @property integer $id
 * @property string $MarketingChannel
 * @property integer $ControllingChannel_id
 *
 * The followings are the available model relations:
 * @property Audibeneid[] $audibenes
 * @property Audibeneid[] $audibenes1
 * @property Controllingchannel $controllingChannel
 * @property Verwendung[] $verwendungs
 */
class Marketingchannel extends CActiveRecord
{
     public $ControllingChannel_search;

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Marketingchannel the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'marketingchannel';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('ControllingChannel_id', 'required'),
            array('ControllingChannel_id', 'numerical', 'integerOnly'=>true),
            array('MarketingChannel', 'length', 'max'=>100),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            //Original   --  array('id, MarketingChannel, ControllingChannel_id', 'safe', 'on'=>'search'),
            array('id, MarketingChannel, ControllingChannel_id, ControllingChannel_search', 'safe', 'on'=>'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'audibenes' => array(self::HAS_MANY, 'Audibeneid', 'MarketingChannel_id'),
            'audibenes1' => array(self::HAS_MANY, 'Audibeneid', 'MarketingChannel_ControllingChannel_id'),
            'controllingChannel' => array(self::BELONGS_TO, 'Controllingchannel', 'ControllingChannel_id'),
            'verwendungs' => array(self::HAS_MANY, 'Verwendung', 'MarketingChannel_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'MarketingChannel' => 'Marketing Channel',
            'ControllingChannel_id' => 'Controlling Channel id',
            'ControllingChannel_search' => 'Controlling Channel',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;
        $criteria->with = array( 'controllingChannel' );
        $criteria->compare('id',$this->id);
        $criteria->compare('MarketingChannel',$this->MarketingChannel,true);
        $criteria->compare('ControllingChannel_id',$this->ControllingChannel_id);
        $criteria->compare( 'controllingChannel.Controllingchannel', $this->ControllingChannel_search, true );
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }
}

Update: Sql of my Table

CREATE TABLE IF NOT EXISTS `marketingchannel` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `MarketingChannel` varchar(100) DEFAULT NULL,
  `ControllingChannel_id` int(11) NOT NULL,
  PRIMARY KEY (`id`,`ControllingChannel_id`),
  UNIQUE KEY `MarketingChannel_UNIQUE` (`MarketingChannel`),
  KEY `fk_MarketingChannel_ControllingChannel1_idx` (`ControllingChannel_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=137 ;

grid view code.

<?php $this->widget('bootstrap.widgets.TbGridView',
array( 'id'=>'marketingchannel-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>
array( 'id', 'MarketingChannel', array( 'name'=>'ControllingChannel_search', 'value'=>'$data->controllingChannel->ControllingChannel' ), 'ControllingChannel_id', 
array( 'class'=>'bootstrap.widgets.TbButtonColumn', ), ), )); ?>
  • 写回答

2条回答 默认 最新

  • doutou3725 2013-12-16 10:54
    关注

    Please change your action code to this and run again.

    public function actionUpdate($id)
    {
    $model=$this->loadModel($id);
    
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($model);
    
    if(isset($_POST['Marketingchannel']))
    {
    $model->attributes=$_POST['Marketingchannel'];
    $model->id = $_GET['id'];
    if($model->save())
    $this->redirect(array('view','id'=>$model->id));
    }
    
    $this->render('update',array(
    'model'=>$model,
    ));
    }
    

    The reason could be due to the miss of id. $model->id might not be set.

    When you have a composite primary key, you should specify it in the array like done below.

    Updated Answer

    public function actionUpdate()
    {
    $id = $_GET['id'];
    $ControllingChannel_id = $_GET['ControllingChannel_id'];
    $model = Marketingchannel::model()->findByPk(array(
    'id' => $id,
    'ControllingChannel_id' => $ControllingChannel_id
    ));
    
    if(isset($_POST['Marketingchannel']))
    {
    $model->attributes=$_POST['Marketingchannel'];
    if($model->save())
    $this->redirect(array('view','id'=>$model->id));
    }
    
    $this->render('update',array(
    'model'=>$model,
    ));
    }
    

    To resolve the incorrect URL in gridview, you should modify your coding as following and include your url (where to go when pencil icon is clicked) . i.e updateButtonUrl = "the Url to update action"

    $this->widget('bootstrap.widgets.TbGridView', array('id'=>'marketingchannel-grid', 'dataProvider'=>$model->search(), 'filter'=>$model,
       'columns'=>
       array('id', 'MarketingChannel', array('name'=>'ControllingChannel_search', 'value'=>'$data->controllingChannel->ControllingChannel')
          , 'ControllingChannel_id',
          array(
             'htmlOptions'=>array('nowrap'=>'nowrap'),
             'class'=>'bootstrap.widgets.TbButtonColumn',
     'updateButtonUrl'=>'Yii::app()->createUrl("Marketingchannel/Update/",array("id"=>$data->id, "ControllingChannel_id"=>$data->ControllingChannel_id))',
          ),
          array('class'=>'bootstrap.widgets.TbButtonColumn'))));
    

    Ref : http://yiibooster.clevertech.biz/widgets/grids/view/gridview.html

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂