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,
]);
}
}
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';
}
}
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.');
}
}
Utilisation
$Prompt->save(false);
Si cela fonctionne, cela signifie qu'une règle de validation échoue.
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.
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.