I'm trying to create a model, apparently all process is right but when I try to show his error in a view (immediately after creating the model) Yii2-app throws
Invalid Configuration – yii\base\InvalidConfigException - "frontend\models\mystore\Staff" must have a primary key.
The only way to solve this problem (until now) is restart MySQL service from my local server and refresh the page on browser, after this my application shows all data without errors, until I create a new record.
I'm using XAMPP like my local server and MySQL like database management system and when I use phpmyadmin to search the new records, all is right, the PK was created and all data is stored correctly.
Model
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']);
}
}
Controller
/**
* 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();
}
}
View
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>
After create the Staff model I expect browser redirect to the index page and all information can be shown in a gridview, but I get the error mentioned above.
next is the complete error message:
"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];
seems that you have not a primary key in your model ( and could be in your table )
you can add a primary key field manually to the model this way
as public static method
class Staff extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'staff';
}
/**
* @inheritdoc$primaryKey
*/
public static function primaryKey()
{
return ["your_id_column"];
}
........
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With