0
votes

Please, I am totally new to Yii1.1, I am following a video tutorial and I have benn trying to follow up closely. I am trying to create and update the album model as indicated in the video tutorial. I typed everything the presenter typed: my codes are given below:

The AlbumController

class AlbumController extends Controller { /** * @var string the default layout for the views. Defaults to '//layouts/column2', meaning * using two-column layout. See 'protected/views/layouts/column2.php'. */ public $layout='//layouts/column2';

/**
 * @return array action filters
 */
public function filters()
{
    return array(
        'accessControl', // perform access control for CRUD operations
        'postOnly + delete', // we only allow deletion via POST request
    );
}

/**
 * Specifies the access control rules.
 * This method is used by the 'accessControl' filter.
 * @return array access control rules
 */
public function accessRules()
{
    return array(
        array('allow',  // allow all users to perform 'index' and 'view' actions
            'actions'=>array('index','view'),
            'users'=>array('*'),
        ),
        array('allow', // allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>array('@'),
        ),
        array('allow', // allow admin user to perform 'admin' and 'delete' actions
            'actions'=>array('admin','delete'),
            'users'=>array('admin'),
        ),
        array('deny',  // deny all users
            'users'=>array('*'),
        ),
    );
}

/**
 * Displays a particular model.
 * @param integer $id the ID of the model to be displayed
 */
public function actionView($id)
{
    $this->render('view',array(
        'model'=>$this->loadModel($id),
    ));
}

/**
 * Creates a new model.
 * If creation is successful, the browser will be redirected to the 'view' page.
 */
public function actionCreate()
{
    $model=new Album;

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

    if(isset($_POST['Album']))
    {
        $model->attributes=$_POST['Album'];
        if($model->save()){
            //$this->redirect(array('view','id'=>$model->id));
                            Yii::app()->user->setFlash('saved', 'Data saved!');
                            $this->redirect(array('update','id'=>$model->id));
                    }
                            else{
                Yii::app()->user->setFlash('failure', 'Data not saved!');
            }


           }

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

/**
 * 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['Album']))
    {
        $model->attributes=$_POST['Album'];
        if($model->save()){
            //$this->redirect(array('view','id'=>$model->id));
                            Yii::app()->user->setFlash('saved', "Data saved!");
                            $this->redirect(array('update','id'=>$model->id));
            }else{
                Yii::app()->user->setFlash('failure', "Data not saved!");
            }


}

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

/**
 * Deletes a particular model.
 * If deletion is successful, the browser will be redirected to the 'admin' page.
 * @param integer $id the ID of the model to be deleted
 */
    }
public function actionDelete($id)
{
    $this->loadModel($id)->delete();

    // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
    if(!isset($_GET['ajax']))
        $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}

/**
 * Lists all models.
 */
public function actionIndex()
{
    $dataProvider=new CActiveDataProvider('Album');
    $this->render('index',array(
        'dataProvider'=>$dataProvider,
    ));
}

/**
 * Manages all models.
 */
public function actionAdmin()
{
    $model=new Album('search');
    $model->unsetAttributes();  // clear any default values
    if(isset($_GET['Album']))
        $model->attributes=$_GET['Album'];

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

/**
 * Returns the data model based on the primary key given in the GET variable.
 * If the data model is not found, an HTTP exception will be raised.
 * @param integer $id the ID of the model to be loaded
 * @return Album the loaded model
 * @throws CHttpException
 */
public function loadModel($id)
{
    $model=Album::model()->findByPk($id);
    if($model===null)
        throw new CHttpException(404,'The requested page does not exist.');
    return $model;
}

/**
 * Performs the AJAX validation.
 * @param Album $model the model to be validated
 */
protected function performAjaxValidation($model)
{
    if(isset($_POST['ajax']) && $_POST['ajax']==='album-form')
    {
        echo CActiveForm::validate($model);
        Yii::app()->end();
    }
}

}

The Album model class

/** * This is the model class for table "tbl_album". * * The followings are the available columns in table 'tbl_album': * @property integer $id * @property string $name * @property string $tags * @property integer $owner_id * @property integer $shareable * @property string $created_dt * * The followings are the available model relations: * @property User $owner * @property Photo[] $photos */ class Album extends CActiveRecord { /** * @return string the associated database table name */ public function tableName() { return 'tbl_album'; }

/**
 * @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('owner_id, shareable, category_id', 'numerical', 'integerOnly'=>true),
        array('name, tags', 'length', 'max'=>255),
                    array('description', 'length', 'max'=>1024),
                    array('description', 'match', 'pattern'=>'/[\w]+/u'),// \-\_\'\ \,\p{L}0-!
        // The following rule is used by search().
        // @todo Please remove those attributes that should not be searched.
        array('id, name, tags, owner_id, shareable, created_dt', 'safe', 'on'=>'search'),
    );
}

/**
 * @return array relational rules.
 */

    //defined function beforeSave()..

    protected function beforeSave(){
        if(parent::beforeSave()){
            if($this->isNewRecord){
                $this->created_dt = new CDbExpression("NOW()");
                $this->owner_id = Yii::app()->user->id;
            }
            return true;
        }else
            return false;

    }

    public function scopes(){
        return array(
            'shareable'=>array(
                'order'=>'created_dt DESC',
                'condition'=>'shareable=1',
            )
    );
    }
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(
        'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),
        'photos' => array(self::HAS_MANY, 'Photo', 'album_id'),
    );
}

/**
 * @return array customized attribute labels (name=>label)
 */
public function attributeLabels()
{
    return array(
        'id' => 'ID',
        'name' => 'Name',
                    'tags' => 'Tags',
        'owner_id' => 'Owner',
                    'category_id'=>'Category',
                    'description'=>'Description',
                    'shareable' => 'Shareable',
        'created_dt' => 'Created Dt',
    );
}

/**
 * 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('name',$this->name,true);
    $criteria->compare('tags',$this->tags,true);
            $criteria->compare('description',$this->description);

    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 Album the static model class
 */
public static function model($className=__CLASS__)
{
    return parent::model($className);
}

}

The Photo Model Class

/** * This is the model class for table "tbl_photo". * * The followings are the available columns in table 'tbl_photo': * @property integer $id * @property integer $album_id * @property string $filename * @property string $caption * @property string $alt_text * @property string $tags * @property integer $sort_order * @property string $created_dt * @property string $lastupdate_dt * * The followings are the available model relations: * @property Comment[] $comments * @property Album $album */

class Photo extends CActiveRecord {
private $_uploads;

/**
 * @return string the associated database table name
 */



public function tableName()
{
    return 'tbl_photo';
}

/**
 * @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('album_id, sort_order', 'numerical', 'integerOnly'=>true),
        array('filename', 'length', 'max'=>500),
        array('tags', 'length', 'max'=>256),
        array('caption, alt_text, created_dt, lastupdate_dt', 'safe'),
        // The following rule is used by search().
        // @todo Please remove those attributes that should not be searched.
        array('id, album_id, filename, caption, alt_text, tags, sort_order, created_dt, lastupdate_dt', '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(
        'comments' => array(self::HAS_MANY, 'Comment', 'photo_id'),
        'album' => array(self::BELONGS_TO, 'Album', 'album_id'),
    );
}

/**
 * @return array customized attribute labels (name=>label)
 */
public function attributeLabels()
{
    return array(
        'id' => 'ID',
        'album_id' => 'Album',
        'filename' => 'Filename',
        'caption' => 'Caption',
        'alt_text' => 'Alt Text',
        'tags' => 'Tags',
        'sort_order' => 'Sort Order',
        'created_dt' => 'Created Dt',
        'lastupdate_dt' => 'Lastupdate Dt',
    );
}

    public function getImageParam(){
     if(empty($this->_uploads)){
         $this->_uploads = Yii::app()->params['uploads']. "/";
         return $this->_uploads;
     }
 }
    public function getUrl(){
    return $this->getImageParam()."uploads/".CHtml::encode($this->filename); 
 }

 public function getThumb(){
     return $this->getImageParam()."thumbs/".CHtml::encode($this->filename);
 }


/**
 * 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('album_id',$this->album_id);
    $criteria->compare('filename',$this->filename,true);
    $criteria->compare('caption',$this->caption,true);
    $criteria->compare('alt_text',$this->alt_text,true);
    $criteria->compare('tags',$this->tags,true);
    $criteria->compare('sort_order',$this->sort_order);
    $criteria->compare('created_dt',$this->created_dt,true);
    $criteria->compare('lastupdate_dt',$this->lastupdate_dt,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 Photo the static model class
 */
public static function model($className=__CLASS__)
{
    return parent::model($className);
}

}

The Photo Model

/** * This is the model class for table "tbl_photo". * * The followings are the available columns in table 'tbl_photo': * @property integer $id * @property integer $album_id * @property string $filename * @property string $caption * @property string $alt_text * @property string $tags * @property integer $sort_order * @property string $created_dt * @property string $lastupdate_dt * * The followings are the available model relations: * @property Comment[] $comments * @property Album $album */

class Photo extends CActiveRecord {
private $_uploads;

/**
 * @return string the associated database table name
 */



public function tableName()
{
    return 'tbl_photo';
}

/**
 * @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('album_id, sort_order', 'numerical', 'integerOnly'=>true),
        array('filename', 'length', 'max'=>500),
        array('tags', 'length', 'max'=>256),
        array('caption, alt_text, created_dt, lastupdate_dt', 'safe'),
        // The following rule is used by search().
        // @todo Please remove those attributes that should not be searched.
        array('id, album_id, filename, caption, alt_text, tags, sort_order, created_dt, lastupdate_dt', '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(
        'comments' => array(self::HAS_MANY, 'Comment', 'photo_id'),
        'album' => array(self::BELONGS_TO, 'Album', 'album_id'),
    );
}

/**
 * @return array customized attribute labels (name=>label)
 */
public function attributeLabels()
{
    return array(
        'id' => 'ID',
        'album_id' => 'Album',
        'filename' => 'Filename',
        'caption' => 'Caption',
        'alt_text' => 'Alt Text',
        'tags' => 'Tags',
        'sort_order' => 'Sort Order',
        'created_dt' => 'Created Dt',
        'lastupdate_dt' => 'Lastupdate Dt',
    );
}

    public function getImageParam(){
     if(empty($this->_uploads)){
         $this->_uploads = Yii::app()->params['uploads']. "/";
         return $this->_uploads;
     }
 }
    public function getUrl(){
    return $this->getImageParam()."uploads/".CHtml::encode($this->filename); 
 }

 public function getThumb(){
     return $this->getImageParam()."thumbs/".CHtml::encode($this->filename);
 }


/**
 * 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('album_id',$this->album_id);
    $criteria->compare('filename',$this->filename,true);
    $criteria->compare('caption',$this->caption,true);
    $criteria->compare('alt_text',$this->alt_text,true);
    $criteria->compare('tags',$this->tags,true);
    $criteria->compare('sort_order',$this->sort_order);
    $criteria->compare('created_dt',$this->created_dt,true);
    $criteria->compare('lastupdate_dt',$this->lastupdate_dt,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 Photo the static model class
 */
public static function model($className=__CLASS__)
{
    return parent::model($className);
}

}

I am getting this error: CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (school2go2.tbl_album, CONSTRAINTtbl_album_ibfk_1FOREIGN KEY (owner_id) REFERENCEStbl_user(id) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: INSERT INTOtbl_album(name,tags,description,shareable,created_dt,owner_id) VALUES (:yp0, :yp1, :yp2, :yp3, NOW(), :yp4)

Please I am totally new to yii and even StackOverflow, pardon my inappropriate editing.I am still learning.

1
Welcome to Stackoverflow. Firstly, please take the time to properly format your code. It makes it more readable. Secondly, it is not necessary to provide the code for your entire application - it is sufficient to just provide the parts relevant to your problem, - crafter
Thanks crafter, I will put that in mind. - user5026490

1 Answers

0
votes

The error translates to: You are trying to insert an album without a corresponding owner.

Impossible to help more without knowing how you got that error.