Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2 active record model not saving data

I've built a simple form model & view, a simple AR model, and a simple controller. The form model assigns the correct values to the AR instance, but when I call save(), none of those values are saved in the DB. Any ideas?

The form model:

<?php

namespace app\models;

use Yii;
use yii\base\Model;

class PromptForm extends Model
{
    public $name;
    public $intro;
    public $prompt;
    public $notes;
    public $questions;


    public function attributeLabels()
    {
        return [
            'name' => 'Prompt title',
            'intro' => 'Intro',
            'prompt' => 'Prompt body',
            'notes' => 'Closing notes',
            'questions' => 'Exploration questions',
        ];
    }

    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            [['name', 'prompt'], 'required'],
            ['name', 'filter', 'filter' => 'trim'],
            ['name', 'string', 'max' => 255],
            [['intro', 'prompt', 'notes', 'questions'], 'default'],
        ];
    }

    public function post()
    {
        if ($this->validate()) {
            $prompt = new Prompt();
            $prompt->name = $this->name;
            $prompt->intro = $this->intro;
            $prompt->prompt = $this->prompt;
            $prompt->notes = $this->notes;
            $prompt->questions = $this->questions;

            $prompt->author = \Yii::$app->user->getId();

            //die(print_r($prompt, TRUE));

            $prompt->save();

            return $prompt;
        }

        return null;
    }
}

The AR model:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

/**
 * Prompt is the model behind the prompt item.
 */
class Prompt extends ActiveRecord
{
    public $name;
    public $intro;
    public $prompt;
    public $notes;
    public $questions;
    public $status;
    public $author;

    public $id;

    /**
     * @return string the name of the table associated with this ActiveRecord class.
     */
    public static function tableName()
    {
        return 'prompt';
    }

    /**
     * @return array the attribute labels.
     */
    public function attributeLabels()
    {
        return [
            'name' => 'Prompt title',
            'intro' => 'Intro',
            'prompt' => 'Prompt body',
            'notes' => 'Closing notes',
            'questions' => 'Exploration questions',
            'status' => 'Status',
            'author' => 'Author ID',
        ];
    }
}

The controller:

<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\PromptForm;
use app\models\Prompt;

class PromptsController extends Controller
{
    public function actionIndex()
    {
        // Return a list of all prompts:
        return $this->render('index');
    }

    public function actionNew()
    {
        if (\Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new PromptForm();
        if ($model->load(Yii::$app->request->post())) {
            if ($prompt = $model->post()) {
                Yii::$app->getSession()->setFlash('success', 'Your prompt was created successfully!');
                return $this->goHome();
            } else {
                Yii::$app->getSession()->setFlash('error', 'Error while submitting your prompt.');
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }
}
like image 727
Tal V. Avatar asked Nov 09 '14 09:11

Tal V.


3 Answers

Okay, I figured it out. Turns out that if you declare public attributes in your ActiveRecord model, they obscure the automatic attributes that are created by AR. Data gets assigned to your obscuring attributes but doesn't get sent into the database.

The correct AR model should have been simply this:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

class Prompt extends ActiveRecord
{
    /**
     * @return string the name of the table associated with this ActiveRecord class.
     */
    public static function tableName()
    {
        return 'prompt';
    }
}
like image 104
Tal V. Avatar answered Nov 19 '22 13:11

Tal V.


Use

$prompt->save(false);

If that works that means that some validation rule fails.

like image 20
NSukonny Avatar answered Nov 19 '22 14:11

NSukonny


Try

    if ($model->load(Yii::$app->request->post())) {
                if ($prompt = $model->post()) {
                    $model->save()
                    Yii::$app->getSession()->setFlash('success', 'Your prompt was created successfully!');
                    return $this->goHome();
                } else {
                    Yii::$app->getSession()->setFlash('error', 'Error while submitting your prompt.');
                }
            }
like image 1
Ajey Avatar answered Nov 19 '22 12:11

Ajey