如何修复Yii2高级模板中的““ frontend \ models \ model”必须具有主键“错误

时间:2019-04-30 22:01:16

标签: php yii2

我正在尝试创建一个模型,显然所有过程都是正确的,但是当我试图在视图中显示他的错误时(立即在创建模型之后),Yii2-app抛出

  

无效的配置-yii \ base \ InvalidConfigException-“ frontend \ models \ mystore \ Staff”必须具有主键。

(直到现在)解决此问题的唯一方法是从本地服务器重新启动MySQL服务并刷新浏览器上的页面,此后我的应用程序将显示所有数据而没有错误,直到创建新记录为止。

我正在使用XAMPP(例如本地服务器)和MySQL(例如数据库管理系统),当我使用phpmyadmin搜索新记录时,一切正常,创建了PK,并且正确存储了所有数据。

型号


namespace frontend\models\mystore;

use Yii;
use frontend\models\basic\PersonalData;
use frontend\models\mystore\Charges;
use frontend\models\mystore\MyStore;
use common\models\User;


/**
 * This is the model class for table "staff".
 *
 * @property int $id
 * @property int $store_id
 * @property string $code 
 * @property int $personal_data_id
 * @property int $charge_id 
 * @property int $active
 * @property int $created_at
 * @property int $updated_at
 * @property int $visible
 * @property int $user_id
 *
 * @property SaleOrders $saleOrders
 * @property User $user
 * @property Charges $charge
 * @property MyStore $store
 * @property PersonalData $personalData
 */
class Staff extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'staff';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['store_id', 'personal_data_id', 'charge_id', 'active', 'created_at', 'updated_at', 'visible', 'user_id'], 'integer'],
            [['code'], 'string', 'max' => 15],
            [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
            [['charge_id'], 'exist', 'skipOnError' => true, 'targetClass' => Charges::className(), 'targetAttribute' => ['charge_id' => 'id']],
            [['store_id'], 'exist', 'skipOnError' => true, 'targetClass' => MyStore::className(), 'targetAttribute' => ['store_id' => 'id']],
            [['personal_data_id'], 'exist', 'skipOnError' => true, 'targetClass' => PersonalData::className(), 'targetAttribute' => ['personal_data_id' => 'id']],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'store_id' => 'Store ID',
            'code' => 'Code',
            'personal_data_id' => 'Personal Data ID',
            'charge_id' => 'Charge ID',
            'active' => 'Active',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'visible' => 'Visible',
            'user_id' => 'User ID',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSaleOrders()
    {
        return $this->hasOne(SaleOrders::className(), ['salesman_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCharge()
    {
        return $this->hasOne(Charges::className(), ['id' => 'charge_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getStore()
    {
        return $this->hasOne(MyStore::className(), ['id' => 'store_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getPersonalData()
    {
        return $this->hasOne(PersonalData::className(), ['id' => 'personal_data_id']);
    }
}

控制器

/**
 * Creates a new Staff model.
 * If creation is successful, the browser will be redirected to the 'index' page.
 * @return mixed
 */
public function actionCreate()
{
    $transaction = \Yii::$app->db->beginTransaction();

    try{
        $staffModel = new Staff();
        $isValid = false;

        $personalDataModels = $this->processPersonalData();// create, load and save personal information, return array with models
        $signupModel = $this->signup(); // create new account
        $personal_data_id = $personalDataModels['persDataModel']->getPrimaryKey(); // get PK when model is stored, get model if not

        if( $personal_data_id && is_int($signupModel) ){ // personal data && user saved correctly

            $staffModel->load(Yii::$app->request->post()); // the only field to be loaded is "code" who is not required

            $staffModel->setAttributes(['store_id' => Yii::$app->user->identity->store, 'personal_data_id' => $personal_data_id, 'active' => 1, 'user_id' => $signupModel ]); // populate the staff model

            $isValid = $staffModel->save();

            if(!$isValid){ // model is not valid
                $transaction->rollBack();
            }
        }

        if($isValid){
            $transaction->commit();

            return $this->redirect(['index']);
        }

        $chargesList = Charges::find()->select(['id', 'name'])->asArray()->all();

        return $this->render('create', [
            'staffModel' => $staffModel,
            'chargesList' => $chargesList,
            'signupModel' => $signupModel,
            'personalModels' => $personalDataModels,
        ]);

    } catch(\Exception $e) {
        $transaction->rollBack();
        throw $e;
    } catch(Exception $e) {
        $transaction->rollback();
    }
}

查看


use yii\helpers\Html;
use yii\grid\GridView;

/* @var $this yii\web\View */
/* @var $searchModel frontend\models\mystore\StaffSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Staff';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="staff-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        <?= Html::a('Create Staff', ['create'], ['class' => 'btn btn-success']) ?>
    </p>

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'code',
            [
                'attribute' => 'name', // public property on searchModel
                'label' => 'Nombre',
                'value' => 'personalData.first_name'// method relation name on main Model . field name
            ],
            [
                'attribute' => 'last_name',
                'label' => 'Apellido',
                'value' => 'personalData.first_last_name'
            ],
            [
                'attribute' => 'charge',
                'label' => 'Cargo',
                'value' => 'charge.name'
            ],
            [
                'attribute' => 'username',
                'label' => 'Nombre de Usuario',
                'value' => 'user.username'
            ],
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
</div>

创建Staff模型后,我希望浏览器重定向到索引页面,并且所有信息都可以显示在gridview中,但是我遇到了上面提到的错误。

下一步是完整的错误消息:

"Invalid Configuration – yii\base\InvalidConfigException
Primary key of 'frontend\models\mystore\Staff' can not be empty."

in C:\xampp\htdocs\myapp\vendor\yiisoft\yii2\db\ActiveQuery.php
  }
                $key = serialize($key);
                if (isset($hash[$key])) {
                    unset($models[$i]);
                } else {
                    $hash[$key] = true;
                }
            }
        } elseif (empty($pks)) {
            throw new InvalidConfigException("Primary key of '{$class}' can not be empty.");
        } else {
            // single column primary key
            $pk = reset($pks);
            foreach ($models as $i => $model) {
                if (!isset($model[$pk])) {
                    // do not continue if the primary key is not part of the result set
                    break;
                }
                $key = $model[$pk];

1 个答案:

答案 0 :(得分:3)

似乎您的模型中没有主键(可能在表中)

您可以通过这种方式将主键字段手动添加到模型中
作为公共静态方法

  class Staff extends \yii\db\ActiveRecord
  {

      /**
       * {@inheritdoc}
       */
      public static function tableName()
      {
          return 'staff';
      }

     /**
       * @inheritdoc$primaryKey
       */
      public static function primaryKey()
      {
          return ["your_id_column"];
      }

   ........