我已经构建了一个简单的表单模型&视图,简单的AR模型和简单的控制器。表单模型为AR实例分配正确的值,但是当我调用save()时,这些值都不会保存在DB中。有什么想法吗?
表单模型:
<?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;
}
}
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',
];
}
}
控制器:
<?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,
]);
}
}
答案 0 :(得分:16)
好的,我明白了。事实证明,如果在ActiveRecord模型中声明公共属性,它们会模糊由AR创建的自动属性。数据被分配给您的模糊属性,但不会被发送到数据库中。
正确的AR模型应该是这样的:
<?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';
}
}
答案 1 :(得分:1)
尝试
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.');
}
}
答案 2 :(得分:1)
使用
$prompt->save(false);
如果有效则意味着某些验证规则失败。
答案 3 :(得分:0)
在控制器中,更改您的if条件如下:
if ($prompt = $model->post() !== null) {
这将验证返回的值不为空 您当前的验证条件仅验证将值分配给变量$ prompt的位置。这就是为什么它总是回归真实的原因。
答案 4 :(得分:0)
当我将Active Record类与Model类结合使用时,我最近遇到了同样的问题。因为我知道AR实际上在Yii2中扩展了Model。为什么不写更少的代码。所以我将代码从模型移动到AR。
$model = new User();
$model->load(Yii::$app->request->post())
但AR的_attribute并没有获得表单中的帖子数据。表单数据实际上在Model对象中。
对象(app \ models \ User)#39(12){[&#34;密码&#34;] =&gt; string(6)&#34; google&#34; [&#34; newpass&#34;] =&GT; NULL [&#34; name&#34;] =&gt; string(5)&#34; Jane1&#34; [&#34;电子邮件&#34;] =&GT;串(16) &#34; jane@outlook.com" [&#34; _attributes&#34;:&#34; YII \分贝\ BaseActiveRecord&#34;:私人] =&GT; array(2){[&#34; password_hash&#34;] =&gt;串(60) &#34; $ $ 2Y $ 13 .vNKpmosLjW / oYAhIezOZOj8rIG6QJvQj8tGHN2x78.75poXVn6Yi&#34; [&#34; AUTH_KEY&#34;] =&GT; string(32)&#34; 4XggNakVd-oeU28ny7obdw7gOmZJ-Rbu&#34; }
只需删除您希望批量分配给AR实例的公共属性即可使其正常工作。
答案 5 :(得分:0)
对于正在为这个问题苦苦挣扎的人,我会记得检查beforeSave
方法(如果存在)。我错误地注释了return
声明。
public function beforeSave($insert)
{
// never toggle comment on this!!!
return parent::beforeSave( $insert);
}
答案 6 :(得分:0)
如何解决
在开发到_form.php
时应添加的第一件事是errorSummary():
<?php $form = ActiveForm::begin(); ?>
// Some input fields
...
<?= $form->errorSummary($model); ?> // <--- Add this
...
<?php ActiveForm::end(); ?>
简化
如果要形成一些最小变化形式,为什么不使用场景呢?
在您的模型中:
public function rules()
{
return [
[['field_1'], 'required', 'on' => self::SCENARIO_ADD], // only on add
[['field_2'], 'required', 'on' => self::SCENARIO_UPDATE], // only on update
[['field_3', 'field_4'], 'required'], // required all the time
];
}
在您的控制器中:
public function actionAdd()
{
$model = new Model();
$model->scenario = Model::SCENARIO_ADD;
if ($model->load(Yii::$app->request->post())) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('add', ['model' => $model]);
}
行为
或者,您可以使用如下行为来代替直接在模型中分配用户:
https://www.yiiframework.com/doc/api/2.0/yii-behaviors-blameablebehavior
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
[
'class' => \yii\behaviors\BlameableBehavior::className(),
'value' => Yii::$app->user->identity->username,
],
[
'class' => \yii\behaviors\TimestampBehavior::className(),
'value' => new \yii\db\Expression('NOW()'),
],
[
'class' => 'sammaye\audittrail\LoggableBehavior',
'userAttribute' => 'updated_by', //blameable attribute of the current model.
'ignored' => ['updated_by', 'updated_at'], // This ignores fields from a selection of all fields, not needed with allowed
],
];
}