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条)

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?