Zapis Liczb Z Formularza W Bazie

Witam.

Rozpoczynam dopiero poznawanie Yii, właściwie to mój pierwszy framework.

Pojawił mi się następujący problem przy zapisie danych z formularza do tabeli.

Za pomocą gii wygenerowałem model i widoki.

Niestety przy dostosowaniu ich chyba coś zepsułem,

gdy usiłuję dodać rekord przez formularz z pustą wartością numeryczną pojawia się błąd:

CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "". The SQL statement executed was: INSERT INTO "Dokumenty" ("rodzaj_dokumentu", "barkod", "qrkod", "data_dostarczenia", "nr_zamowienia", "klient", "ścieżka_do_skanu") VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6)

Jak namierzyć ten błąd ?

Załączam stos. Baza Postgres 9.3.2 , Yii 1.1.14




Stack Trace

#0 	

+

 /var/www/yii-1.1.14/framework/db/ar/CActiveRecord.php(1077): CDbCommand->execute()

#1 	

+

 /var/www/yii-1.1.14/framework/db/ar/CActiveRecord.php(806): CActiveRecord->insert(null)

#2 	

–

 /var/www/html/yii/protected/controllers/DokumentyController.php(71): CActiveRecord->save()


66         // $this->performAjaxValidation($model);

67 

68         if(isset($_POST['Dokumenty']))

69         {

70             $model->attributes=$_POST['Dokumenty'];

71             if($model->save())

72                 $this->redirect(array('view','id'=>$model->id));

73         }

74 

75         $this->render('create',array(

76             'model'=>$model,


#3 	

+

 /var/www/yii-1.1.14/framework/web/actions/CInlineAction.php(49): DokumentyController->actionCreate()

#4 	

+

 /var/www/yii-1.1.14/framework/web/CController.php(308): CInlineAction->runWithParams(array("r" => "dokumenty/create"))

#5 	

+

 /var/www/yii-1.1.14/framework/web/filters/CFilterChain.php(133): CController->runAction(CInlineAction)

#6 	

+

 /var/www/yii-1.1.14/framework/web/filters/CFilter.php(40): CFilterChain->run()

#7 	

+

 /var/www/yii-1.1.14/framework/web/CController.php(1145): CFilter->filter(CFilterChain)

#8 	

+

 /var/www/yii-1.1.14/framework/web/filters/CInlineFilter.php(58): CController->filterAccessControl(CFilterChain)

#9 	

+

 /var/www/yii-1.1.14/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter(CFilterChain)

#10 	

+

 /var/www/yii-1.1.14/framework/web/CController.php(291): CFilterChain->run()

#11 	

+

 /var/www/yii-1.1.14/framework/web/CController.php(265): CController->runActionWithFilters(CInlineAction, array("accessControl", "postOnly + delete"))

#12 	

+

 /var/www/yii-1.1.14/framework/web/CWebApplication.php(282): CController->run("create")

#13 	

+

 /var/www/yii-1.1.14/framework/web/CWebApplication.php(141): CWebApplication->runController("dokumenty/create")

#14 	

+

 /var/www/yii-1.1.14/framework/base/CApplication.php(180): CWebApplication->processRequest()

#15 	

–

 /var/www/html/yii/index.php(13): CApplication->run()


08 defined('YII_DEBUG') or define('YII_DEBUG',true);

09 // specify how many levels of call stack should be shown in each log message

10 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

11 

12 require_once($yii);

13 Yii::createWebApplication($config)->run();



Cześć,

Sprawdź najpierw w bazie danych czy pole może być null.

Pola numeryczne nr_zamowienia, barkod mogą być nullami.

Dołączanie rekordów bezpośrednio w bazie działa.

Co dziwne dodanie wypełnionego rekordu, a następnie aktualizacja do null

działa.

  1. Zrób var_dump() w zaznaczonych miejscach (po zatwierdzeniu form z danymi które powodują błąd) i wklej.



   if(isset($_POST['Dokumenty'])){

            // var_dump($_POST['Dokumenty']);

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

            // var_dump($model);

            if($model->save())

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

}

  1. Pokaż klasę modelu.

Wynik dumpów




array (size=7)

  'rodzaj_dokumentu' => string 'faktura' (length=7)

  'barkod' => string '' (length=0)

  'qrkod' => string '' (length=0)

  'data_dostarczenia' => string '' (length=0)

  'nr_zamowienia' => string '' (length=0)

  'klient' => string '' (length=0)

  'sciezka_do_skanu' => string '' (length=0)


object(Dokumenty)[22]

  private '_new' (CActiveRecord) => boolean true

  private '_attributes' (CActiveRecord) => 

    array (size=7)

      'rodzaj_dokumentu' => string 'faktura' (length=7)

      'barkod' => string '' (length=0)

      'qrkod' => string '' (length=0)

      'data_dostarczenia' => string '' (length=0)

      'nr_zamowienia' => string '' (length=0)

      'klient' => string '' (length=0)

      'sciezka_do_skanu' => string '' (length=0)

  private '_related' (CActiveRecord) => 

    array (size=0)

      empty

  private '_c' (CActiveRecord) => null

  private '_pk' (CActiveRecord) => null

  private '_alias' (CActiveRecord) => string 't' (length=1)

  private '_errors' (CModel) => 

    array (size=0)

      empty

  private '_validators' (CModel) => 

    object(CList)[29]

      private '_d' => 

        array (size=4)

          0 => 

            object(CNumberValidator)[38]

              ...

          1 => 

            object(CExistValidator)[39]

              ...

          2 => 

            object(CSafeValidator)[40]

              ...

          3 => 

            object(CSafeValidator)[41]

              ...

      private '_c' => int 4

      private '_r' => boolean false

      private '_e' (CComponent) => null

      private '_m' (CComponent) => null

  private '_scenario' (CModel) => string 'insert' (length=6)

  private '_e' (CComponent) => null

  private '_m' (CComponent) => null


CDbException


CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "". The SQL statement executed was: INSERT INTO "Dokumenty" ("rodzaj_dokumentu", "barkod", "qrkod", "data_dostarczenia", "nr_zamowienia", "klient", "sciezka_do_skanu") VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6) 



Klasa modelu




<?php


/**

 * This is the model class for table "Dokumenty".

 *

 * The followings are the available columns in table 'Dokumenty':

 * @property integer $id

 * @property string $rodzaj_dokumentu

 * @property string $barkod

 * @property string $qrkod

 * @property string $data_dostarczenia

 * @property integer $nr_zamowienia

 * @property string $klient

 * @property string $sciezka_do_skanu

 *

 * The followings are the available model relations:

 * @property RodzajeDokumentow $rodzajDokumentu

 */

class Dokumenty extends CActiveRecord

{

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'Dokumenty';

	}


	/**

	 * @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('nr_zamowienia, barkod', 'numerical', 'integerOnly'=>true),

			array('rodzaj_dokumentu', 'exist', 'className'=>'RodzajeDokumentow'),

			array('qrkod, data_dostarczenia, klient, sciezka_do_skanu', 'safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, rodzaj_dokumentu, barkod, qrkod, data_dostarczenia, nr_zamowienia, klient', '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(

			'rodzajDokumentu' => array(self::BELONGS_TO, 'RodzajeDokumentow', 'rodzaj_dokumentu'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'rodzaj_dokumentu' => 'Rodzaj dokumentu',

			'barkod' => 'Barkod',

			'qrkod' => 'Qr kod',

			'data_dostarczenia' => 'Data dostarczenia dokumentu',

			'nr_zamowienia' => 'Numer zamówienia',

			'klient' => 'Nazwa klienta',

			'sciezka_do_skanu' => 'Skan',

		);

	}


	/**

	 * 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('rodzaj_dokumentu',$this->rodzaj_dokumentu,true);

		$criteria->compare('barkod',$this->barkod,true);

		$criteria->compare('qrkod',$this->qrkod,true);

		$criteria->compare('data_dostarczenia',$this->data_dostarczenia,true);

		$criteria->compare('nr_zamowienia',$this->nr_zamowienia);

		$criteria->compare('klient',$this->klient,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 Dokumenty the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}






Kod wygląda ok, znalazłem na forum podobne pytanie tu http://www.yiiframework.com/forum/index.php/topic/7683-cdbexception-on-inserting-empty-value-for-numeric-fields/

Proponowane rozwiązanie to ustawianie wartości domyślnych gdy pole jest pustym stringiem, np:




public function rules(){

return array(

   ...

   array('field','default','setOnEmpty'=>true,'value'=>0),

   ...

)



Dziękuję za link, najbardziej podoba mi się to rozwiązanie

z nadpisaniem beforeSave.

Tym bardzej że ten sam problem pojawił się przy dacie.