Yii三次从表格中保存记录


Yii saves record from form 3 times

我的控制器中有以下操作:

public function actionEntersales()
{
    $model = new Sales();
    if (!isset($_POST['Sales'])) {
        $model->receipt_date = date("Y-m-d", time());
    }
    if (isset($_POST['Sales'])) {
        $model->attributes = $_POST['Sales'];
        if ($model->validate()):
            $model->save();
            $this->redirect(array('company/comissionmanagement'));
        endif;
    }
    $this->render('entersales', array(
        'model' => $model,
    ));
}

它应该验证然后保存表单数据,其中"sales_items"必须一个接一个地保存在另一个表中。

我试图通过在"特征"上使用前臂来达到这个目标。

这是相关的模型:

<?php
/**
 * This is the model class for table "sales".
 *
 * The followings are the available columns in table 'sales':
 * @property integer $id
 * @property integer $company_id
 * @property integer $user_id
 * @property integer $store_id
 * @property integer $receipt_no
 * @property string $receipt_date
 * @property integer $carrier_id
 * @property integer $activationtype_id
 * @property string $mdn
 * @property string $accountpin
 * @property integer $rateplans_id
 * @property integer $status3_id
 * @property string $created
 * @property string $modified
 *
 * The followings are the available model relations:
 * @property Activationtypes $activationtype
 * @property Companies $company
 * @property Rateplans $rateplans
 * @property Stores $store
 * @property Users $user
 * @property Carriers $carrier
 * @property SalesItems[] $salesItems
 */
class Sales extends CActiveRecord
{
    /**
     * @return string the associated database table name
     */
    public $features;
    public function tableName()
    {
        return 'sales';
    }
    /**
     * @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('company_id, user_id, store_id, receipt_no, receipt_date, carrier_id, activationtype_id, serial, mdn, accountpin, rateplans_id, status3_id', 'required'),
            array('company_id, user_id, store_id, receipt_no, carrier_id, activationtype_id, rateplans_id, status3_id', 'numerical', 'integerOnly' => true),
            array('mdn, accountpin', 'length', 'max' => 10),
            array('serial', 'length', 'max' => 18),
            array('modified', 'safe'),
            array('features', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, company_id, user_id, store_id, receipt_no, receipt_date, carrier_id, activationtype_id, serial, mdn, accountpin, rateplans_id, status3_id, created, modified', '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(
            'activationtype' => array(self::BELONGS_TO, 'Activationtypes', 'activationtype_id'),
            'company' => array(self::BELONGS_TO, 'Companies', 'company_id'),
            'rateplans' => array(self::BELONGS_TO, 'Rateplans', 'rateplans_id'),
            'store' => array(self::BELONGS_TO, 'Stores', 'store_id'),
            'user' => array(self::BELONGS_TO, 'Users', 'user_id'),
            'carrier' => array(self::BELONGS_TO, 'Carriers', 'carrier_id'),
            'salesItems' => array(self::HAS_MANY, 'SalesItems', 'sales_id'),
        );
    }
    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'company_id' => 'Company',
            'user_id' => 'User',
            'store_id' => 'Store',
            'receipt_no' => 'Receipt No',
            'receipt_date' => 'Receipt Date',
            'carrier_id' => 'Carrier',
            'activationtype_id' => 'Activationtype',
            'serial' => ' Serial Number',
            'mdn' => 'Mdn',
            'accountpin' => 'Accountpin',
            'rateplans_id' => 'Rateplans',
            'status3_id' => 'Status3',
            'created' => 'Created',
            'modified' => 'Modified',
        );
    }
    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.
        $criteria = new CDbCriteria;
        $criteria->compare('id', $this->id);
        $criteria->compare('company_id', Yii::app()->user->cid);
        $criteria->compare('user_id', $this->user_id);
        $criteria->compare('store_id', $this->store_id);
        $criteria->compare('receipt_no', $this->receipt_no);
        $criteria->compare('receipt_date', $this->receipt_date, true);
        $criteria->compare('carrier_id', $this->carrier_id);
        $criteria->compare('activationtype_id', $this->activationtype_id);
        $criteria->compare('serial', $this->serial, true);
        $criteria->compare('mdn', $this->mdn, true);
        $criteria->compare('accountpin', $this->accountpin, true);
        $criteria->compare('rateplans_id', $this->rateplans_id);
        $criteria->compare('status3_id', $this->status3_id);
        $criteria->compare('created', $this->created, true);
        $criteria->compare('modified', $this->modified, true);
        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }
    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Sales the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }
    public function beforeValidate()
    {
        $this->company_id = Yii::app()->user->cid;
        $this->status3_id = 0;
        return parent::beforeValidate();
    }
    public function afterSave()
    {
        if (count($this->features) > 0):
            $sid = $this->id;
            foreach ($this->features as $key => $fid):
                $si = new SalesItems();
                $si->sales_id = $sid;
                $si->feature_id = $fid;
                $si->status2_id = 0;
                $si->save(false);
            endforeach;
        endif;
        return parent::afterSave();
    }
}

当我提交表单时,它保存了3次记录,包括所有sales_items记录3次。

我在代码中看不出它为什么会这样。

最好将两个表保存在同一个控制器操作中。。。如果这些值不是由用户输入的,那么会更容易,否则您也需要相应地更改表单/视图。一旦你的表格准备好了,你可以尝试下面这样的东西(粗略的代码,但你已经明白了)。。。

$model = new Sales();
    if (!isset($_POST['Sales'])) {
        $model->receipt_date = date("Y-m-d", time());
    }
    if (isset($_POST['Sales'])) {
        $model->attributes = $_POST['Sales'];
        if ($model->validate()):
            if($model->save(false))  
                {
                  if (count($this->features) > 0):
                    $sid = $this->id;
                    foreach ($this->features as $key => $fid):
                        $si = new SalesItems();
                      ........
                      ......
                  }    

    }