web-dev-qa-db-fra.com

Le modèle d'enregistrement actif Yii2 ne sauvegarde pas les données

J'ai construit un modèle de formulaire simple et une vue, un modèle AR simple et un contrôleur simple. Le modèle de formulaire attribue les valeurs correctes à l'instance AR, mais lorsque j'appelle save (), aucune de ces valeurs n'est enregistrée dans le DB. Des idées?

Le modèle de formulaire:

<?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;
    }
}

Le modèle AR:

<?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',
        ];
    }
}

Le controlle:

<?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,
        ]);
    }
}
11
Tal V.

Ok, je l'ai compris. Il s'avère que si vous déclarez des attributs publics dans votre modèle ActiveRecord, ils masquent les attributs automatiques créés par AR. Les données sont affectées à vos attributs de masquage mais ne sont pas envoyées dans la base de données.

Le modèle AR correct aurait dû être simplement ceci:

<?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';
    }
}
16
Tal V.

Essayer 

    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.');
                }
            }
1
Ajey

Utilisation 

$Prompt->save(false);

Si cela fonctionne, cela signifie qu'une règle de validation échoue. 

1
KajeNick

Dans le contrôleur, changez votre condition si comme suit: 

if ($Prompt = $model->post() !== null) {

Cela validera que la valeur qui est retournée n'est pas nulle.
Votre condition de validation actuelle ne valide que lorsque la valeur est affectée à la variable $ Prompt ou non. Et c'est pourquoi cela retourne toujours vrai.

0
Akshay Vanjare

J'ai rencontré le même problème récemment, lorsque je combinais la classe Active Record avec la classe Model. Parce que je sais que AR étend réellement le modèle dans Yii2 Pourquoi ne pas écrire moins de code.Alors je déplace le code du modèle vers le RA.

$model = new User();  
$model->load(Yii::$app->request->post())

Mais l'attribut de l'AR n'a pas reçu les données de poste dans le formulaire. les données de formulaire sont en réalité dans un objet Model.

objet (app\models\User) # 39 (12) {["mot de passe"] => chaîne (6) "google" ["newpass"] => NULL ["nom"] => chaîne ( 5) "Jane1" ["email"] => string (16) "[email protected]" ["_attributes": "yii\db\BaseActiveRecord": privé] => array (2) {["password_hash"] => string (60) "$ 2y $ 13 $ .vNKpmosLjW/oYAhIezOZOj8rIG6QJvQj8tGHN2x78.75poXVn6Yi" ["clé_auto") 4XggNakVd-oeU28ny7obdw7gOmZJ-Rbu "}

supprimez simplement l'attribut public que vous souhaitez affecter en masse à l'instance AR le fera fonctionner.

0
tyan