16

Previously, I was not using $model->save() function for inserting or updating any data. I was simply using createCommand() to execute query and it was working successfully. But, my team members asked me to avoid createCommand() and use $model->save();

Now, I started cleaning my code and problem is $model->save(); not working for me. I don't know where i did mistake.

UsersController.php (Controller)

<?php
namespace app\modules\users\controllers;
use Yii;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\swiftmailer\Mailer;
use yii\filters\AccessControl;
use yii\web\Response;
use yii\widgets\ActiveForm;
use app\modules\users\models\Users;
use app\controllers\CommonController;

class UsersController extends CommonController 
{
    .
    .

    public function actionRegister() {
    $model = new Users();

        // For Ajax Email Exist Validation
   if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())){
     Yii::$app->response->format = Response::FORMAT_JSON;
     return ActiveForm::validate($model);
   } 

   else if ($model->load(Yii::$app->request->post())) {
      $post = Yii::$app->request->post('Users');
      $CheckExistingUser = $model->findOne(['email' => $post['email']]);

      // Ok. Email Doesn't Exist
      if(!$CheckExistingUser) {

        $auth_key = $model->getConfirmationLink();
        $password = md5($post['password']);
        $registration_ip = Yii::$app->getRequest()->getUserIP();
        $created_at = date('Y-m-d h:i:s');

        $model->auth_key = $auth_key;
        $model->password = $password;
        $model->registration_ip = $registration_ip;
        $model->created_at = $created_at;

        if($model->save()) {
          print_r("asd");
        }

      }

    } 
    }
    .
    .
}

Everything OK in this except $model->save(); Not printing 'asd' as i echoed it.

And, if i write

else if ($model->load(Yii::$app->request->post() && $model->validate()) {

}

It's not entering to this if condition.

And, if i write

if($model->save(false)) {
    print_r("asd");
}

It insert NULL to all columns and print 'asd'

Users.php (model)

<?php

namespace app\modules\users\models;

use Yii;
use yii\base\Model;
use yii\db\ActiveRecord;
use yii\helpers\Security;
use yii\web\IdentityInterface;
use app\modules\users\models\UserType;

class Users extends ActiveRecord implements IdentityInterface 
{

  public $id;
  public $first_name;
  public $last_name;
  public $email;
  public $password;
  public $rememberMe;
  public $confirm_password;
  public $user_type;
  public $company_name;
  public $status;
  public $auth_key;
  public $confirmed_at;
  public $registration_ip;
  public $verify_code;
  public $created_at;
  public $updated_at;
  public $_user = false;

  public static function tableName() {
    return 'users';
  }

  public function rules() {
    return [
      //First Name
      'FirstNameLength' => ['first_name', 'string', 'min' => 3, 'max' => 255],
      'FirstNameTrim' => ['first_name', 'filter', 'filter' => 'trim'],
      'FirstNameRequired' => ['first_name', 'required'],
      //Last Name
      'LastNameLength' => ['last_name', 'string', 'min' => 3, 'max' => 255],
      'LastNameTrim' => ['last_name', 'filter', 'filter' => 'trim'],
      'LastNameRequired' => ['last_name', 'required'],
      //Email ID
      'emailTrim' => ['email', 'filter', 'filter' => 'trim'],
      'emailRequired' => ['email', 'required'],
      'emailPattern' => ['email', 'email'],
      'emailUnique' => ['email', 'unique', 'message' => 'Email already exists!'],
      //Password
      'passwordRequired' => ['password', 'required'],
      'passwordLength' => ['password', 'string', 'min' => 6],
      //Confirm Password
      'ConfirmPasswordRequired' => ['confirm_password', 'required'],
      'ConfirmPasswordLength' => ['confirm_password', 'string', 'min' => 6],
      ['confirm_password', 'compare', 'compareAttribute' => 'password'],
      //Admin Type
      ['user_type', 'required'],
      //company_name
      ['company_name', 'required', 'when' => function($model) {
          return ($model->user_type == 2 ? true : false);
        }, 'whenClient' => "function (attribute, value) {
          return $('input[type=\"radio\"][name=\"Users[user_type]\"]:checked').val() == 2;
      }"], #'enableClientValidation' => false
      //Captcha
      ['verify_code', 'captcha'],

      [['auth_key','registration_ip','created_at'],'safe'] 
    ];
  }

  public function attributeLabels() {
    return [
      'id' => 'ID',
      'first_name' => 'First Name',
      'last_name' => 'Last Name',
      'email' => 'Email',
      'password' => 'Password',
      'user_type' => 'User Type',
      'company_name' => 'Company Name',
      'status' => 'Status',
      'auth_key' => 'Auth Key',
      'confirmed_at' => 'Confirmed At',
      'registration_ip' => 'Registration Ip',
      'confirm_id' => 'Confirm ID',
      'created_at' => 'Created At',
      'updated_at' => 'Updated At',
      'verify_code' => 'Verification Code',
    ];
  }

  //custom methods
  public static function findIdentity($id) {
    return static::findOne($id);
  }

  public static function instantiate($row) {
    return new static($row);
  }

  public static function findIdentityByAccessToken($token, $type = null) {
    throw new NotSupportedException('Method "' . __CLASS__ . '::' . __METHOD__ . '" is not implemented.');
  }

  public function getId() {
    return $this->id;
  }

  public function getAuthKey() {
    return $this->auth_key;
  }

  public function validateAuthKey($authKey) {
    return $this->auth_key === $auth_key;
  }

  public function validatePassword($password) {
    return $this->password === $password;
  }

  public function getFirstName() {
    return $this->first_name;
  }

  public function getLastName() {
    return $this->last_name;
  }

  public function getEmail() {
    return $this->email;
  }

  public function getCompanyName() {
    return $this->company_name;
  }

  public function getUserType() {
    return $this->user_type;
  }

  public function getStatus() {
    return $this->status;
  }

  public function getUserTypeValue() {
    $UserType = $this->user_type;
    $UserTypeValue = UserType::find()->select(['type'])->where(['id' => $UserType])->one();
    return $UserTypeValue['type'];
  }

  public function getCreatedAtDate() {
    $CreatedAtDate = $this->created_at;
    $CreatedAtDate = date('d-m-Y h:i:s A', strtotime($CreatedAtDate));
    return $CreatedAtDate;
  }

  public function getLastUpdatedDate() {
    $UpdatedDate = $this->updated_at;
    if ($UpdatedDate != 0) {
      $UpdatedDate = date('d-m-Y h:i:s A', strtotime($UpdatedDate));
      return $UpdatedDate;
    } else {
      return '';
    }
  }

  public function register() {
    if ($this->validate()) {
      return true;
    }
    return false;
  }

  public static function findByEmailAndPassword($email, $password) {
    $password = md5($password);
    $model = Yii::$app->db->createCommand("SELECT * FROM users WHERE email ='{$email}' AND password='{$password}' AND status=1");
    $users = $model->queryOne();
    if (!empty($users)) {
      return new Users($users);
    } else {
      return false;
    }
  }

  public static function getConfirmationLink() {
    $characters = 'abcedefghijklmnopqrstuvwxyzzyxwvutsrqponmlk';
    $confirmLinkID = '';
    for ($i = 0; $i < 10; $i++) {
      $confirmLinkID .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $confirmLinkID = md5($confirmLinkID);
  }

}

Any help is appreciable. Please Help me.

Nana Partykar
  • 10,175
  • 8
  • 43
  • 73
  • 1
    Most likely a problem with your form. Check that `Yii::$app->request->post()` is populated correctly. – chris--- Nov 17 '15 at 14:53
  • Hi Mr @chris--- , I did `print_r(Yii::$app->request->post());` It echoed the value which I entered in form. – Nana Partykar Nov 17 '15 at 14:56
  • Ok weird. Check that the model is populated correctly right after the above line doing a `var_dump($model->attributes);` Also you messed up the parathesis in the line `else if ($model->load(Yii::$app->request->post() && $model->validate()))` above, where you say its not wentering the if condition. It should be `else if ($model->load(Yii::$app->request->post()) && $model->validate())` – chris--- Nov 17 '15 at 15:01
  • `var_dump($model->attributes);` first line inside `else if ($model->load(Yii::$app->request->post())) { }` it echoing value @chris--- and, that `$model->validate()))` was typo. Sorry. – Nana Partykar Nov 17 '15 at 15:12
  • `var_dump($model->attributes);` just after `$model = new Users();` it echoing NULL for all field @chris--- – Nana Partykar Nov 17 '15 at 15:15
  • That is expected but what is the model after the `load` method? – chris--- Nov 17 '15 at 15:20
  • After load method, it is echoing @chris--- – Nana Partykar Nov 17 '15 at 15:20
  • try print the errors _$model->getErrors()_ in the `if($model->save(false)) { print_r("asd"); } else { echo'
    ';print_r($model->getErrors()); exit(); }`
    – David Nov 17 '15 at 16:01
  • Do you have validation rules and/or scenarios defined in the Users class? – robsch Nov 17 '15 at 16:03
  • Hi @David : When i do `if($model->save(false))` NULL getting inserted into table. When i write `print_r($model->getErrors());` inside `if($model->save(false))` . Output coming: **Array ( )** – Nana Partykar Nov 17 '15 at 17:07
  • sorry can you try to using _$model->save()_ instead of _$model->save(false)_ and then _print_r($model->getErrors());_. because _$model->save(false)_ will skip validations – David Nov 17 '15 at 17:23
  • Hi @David : I got this `Array ( [confirm_password] => Array ( [0] => Confirm Password must be repeated exactly. ) [verify_code] => Array ( [0] => The verification code is incorrect. ) )` – Nana Partykar Nov 17 '15 at 17:26
  • those're the errors that prevent the model to be saved. it tells that the confirm password is differ from the password and the inputed captcha is incorect. could you check them – David Nov 17 '15 at 17:51
  • I Checked them. It's correct @David – Nana Partykar Nov 17 '15 at 17:54
  • Even, i removed `confirm-password` and `captcha` from my form. But, this time it entered `$modal->save()` function but, inserted NULL to each table field @David – Nana Partykar Nov 17 '15 at 17:59
  • so your validation rules is all passed, then try what @scaisEdge said, removing defining properties in _Users_ class that belong to the table fields – David Nov 17 '15 at 18:55
  • See this solution, it can help you [New record isn't saved and no error messages](https://stackoverflow.com/questions/15770726/new-record-isnt-saved-and-no-error-messages/44593783#44593783) – Malki Mohamed Jun 16 '17 at 16:21
  • I tried both `print_r(Yii::$app->request->post())` and `print_r($m->getErrors())`. Both are giving me and empty array `Array()` – Moeez Feb 08 '18 at 10:52
  • As I said in https://stackoverflow.com/a/56127720/1546049, always check for the `beforeSave` method if exists, and look for the proper `return` statement. – Gianpaolo Scrigna May 14 '19 at 10:49

10 Answers10

45

It could be a problem related with your validation rules.

Try, as a test, to save the model without any validation in this way:

$model->save(false);

If the model is saved you have conflict with your validation rules. Try selectively removing your validation rule(s) to find the validation conflict.

If you have redefined the value present in active record you don't assign the value to the var for db but for this new var and then are not save.

Try removing the duplicated var.. (only the vars non mapped to db should be declared here.)

Bibek Lekhak
  • 51
  • 1
  • 7
scaisEdge
  • 124,973
  • 10
  • 73
  • 87
  • Hi Mr Scais. When i use `$model->save(false);`. NULL is getting inserted to table. – Nana Partykar Nov 17 '15 at 17:02
  • I Updated my question with Model Mr @Scais. – Nana Partykar Nov 17 '15 at 17:10
  • But you have redifined the value present in active record... I have update the answer... You are not using insert anymore.. you are using active record – scaisEdge Nov 17 '15 at 17:22
  • Sorry @Scais. I didn't get. Really Sorry. – Nana Partykar Nov 17 '15 at 17:24
  • 1
    You do not have to be sorry this is a mistake that I have made several times ... The important thing is that the answer is correct and that your programs to operate it properly – scaisEdge Nov 17 '15 at 17:28
  • Ok @Scais. If you don't mind, Can you point out the changes i need to do in my Users.php Model. If possible, can you give One example. – Nana Partykar Nov 17 '15 at 17:44
  • Is easy simply remove Or comment) the vars with same name of the column table of your user table... You can do it progressively if you want test.... – scaisEdge Nov 17 '15 at 17:48
  • This wan not an easy answer. I hoped it was also accepted as well as helpful – scaisEdge Nov 18 '15 at 19:16
  • Yeah @Scais. From Yesterday I was banging my head. Now issue is resolved. And, at last your **suggestion/answer** came into existence. Thank You so much for spending time. It is always an honour to get **answer/comment** from you. – Nana Partykar Nov 18 '15 at 19:21
  • 1
    I have see you take the wrong road but i not insisted in my answer. (I know by my personal experience was right). I have hoped you return to my suggestion. The knowledge in our fields is a precoius stuff. Good Work and thanks.. – scaisEdge Nov 18 '15 at 19:26
21

I guess $model->load() returns false, call $model->errors to see model's error.

$model->load();
$model->validate();
var_dump($model->errors);
arogachev
  • 31,868
  • 6
  • 105
  • 113
Pavle Li
  • 219
  • 1
  • 3
5

Check model saving error like this :

if ($model->save()) {

} else {
  echo "MODEL NOT SAVED";
  print_r($model->getAttributes());
  print_r($model->getErrors());
  exit;
}
Ruslan Novikov
  • 856
  • 12
  • 18
4

As @scaisEdge suggest, try removing all table related field in your Users class

class Users extends ActiveRecord implements IdentityInterface 
{
  /* removed because this properties is related in a table's field 
  public $first_name;
  public $last_name;
  public $email;
  public $password;
  public $user_type;
  public $company_name;
  public $status;
  public $auth_key;
  public $confirmed_at;
  public $registration_ip;
  public $verify_code;
  public $created_at;
  public $updated_at;
  public $user_type;
  public $company_name;
  public $status;
  public $auth_key;
  public $confirmed_at;
  public $registration_ip;
  public $verify_code;
  public $created_at;
  public $updated_at;
  */

  // this is properties that not related to users table
  public $rememberMe;
  public $confirm_password;
  public $_user = false;

  public static function tableName() {
    return 'users';
  }

 /* ........... */

}
David
  • 492
  • 3
  • 5
1

You are doing all staff correct. I think u must add one line for confirm password validation

if(!$CheckExistingUser) {    
$auth_key = $model->getConfirmationLink();
        $password = md5($post['password']);
        $registration_ip = Yii::$app->getRequest()->getUserIP();
        $created_at = date('Y-m-d h:i:s');

        $model->auth_key = $auth_key;
        $model->password = $password;
        $model->confirm_password= md5($post["confirm_password"]);  /// add  this line
        $model->registration_ip = $registration_ip;
        $model->created_at = $created_at;

And Also after this condition check model attributes and error like this :

if($model->save()) {
          print_r("asd");
        }else{
var_dump($model);exit;}
  • Hi @Nuriddin. Glad to see you bro. No insertion in table. Help me man. Past 6 Hours, I have been stuck to it. – Nana Partykar Nov 17 '15 at 18:27
  • Hi @Partykar Are u test my answer – Nuriddin Rashidov Nov 17 '15 at 18:30
  • Yeah. I did. Even, i add `captcha` to it. But, no result man. Now, my brain also stopped working. One more answer @Scais Has given above, but i'm not able to understand what he is saying. Do something @nuriddin. – Nana Partykar Nov 17 '15 at 18:31
  • Can u post the result of this : if($model->save() )-> see my post :-> var_dump($model); – Nuriddin Rashidov Nov 17 '15 at 18:33
  • It printed lot of things @nuriddin. `["id"]=> NULL ["first_name"]=> string(6) "danish" ["last_name"]=> string(4) "enam" ["email"]=> string(14) "danish@jbk.com" ["password"]=> string(32) "e10adc3949ba59abbe56e057f20f883e" ["rememberMe"]=> NULL ["confirm_password"]=> string(6) "123456" ["user_type"]=> string(1) "1" ["company_name"]=> string(0) "" ["status"]=> NULL ["auth_key"]=> string(32) "5276a550bf50d7bdd2067a63c32e0daf" ["confirmed_at"]=> NULL` Thses are the first few lines – Nana Partykar Nov 17 '15 at 18:36
  • Can you do this, i think you confirm_password and password not equal to each other because of md5, pls try $model->confirm_password= md5($post["confirm_password"]); for test reason. If it is work, we can do this yii2 way ;) – Nuriddin Rashidov Nov 17 '15 at 18:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95377/discussion-between-nana-partykar-and-nuriddin-rashidov). – Nana Partykar Nov 17 '15 at 18:40
  • Hi @NanaPartykar, thanks for remembering me my friend. These day i was busy with my new projects and is going great. How about you? – Nuriddin Rashidov Jan 23 '16 at 20:11
1

The other solution mentioned $model->save(false);. That is just a temporary workaround, and you should still find the actual reason why the save functionality is not working.

Here are additional steps to help diagnose the actual issue:

  1. check that _form input field has the proper name, and
  2. check that if you have added any dropdown functionality, then check whether it's working properly or not
Samuel Liew
  • 68,352
  • 105
  • 140
  • 225
Devang
  • 11
  • 1
1

And there maybe another reason of not saving model - you have property of your Users class and before saving from form its reset to NULL.

So, if you set $model->saveAttributes('favorite_book'=>$model->favorite_book), but at that time you declared in class Users public $favorite_book - you will get this field empty in DB.

stakavi
  • 31
  • 2
0

Try this:

$model->save(false);

and if thats working, check your model rules() and your form rules() if its having the same rules. usually the cause is the required fields in your table.

kaizer
  • 27
  • 1
  • 2
0

if your column type in your table is "integer" and your data is "string" you may see tis error.You should check your data type and try again.

I suppose that your column type is integer, you should write the following code:

$model->created_at=time();//1499722038
$model->save(); 

but your column type is string, you should write the following code:

$model->created_at=date('d/m/Y');//11/07/2017
$model->save(); 
Mahmut Aydın
  • 715
  • 10
  • 21
-1

in your model i found First name , last name , email , password is required fields and in your controller you are updating or saving only

 $model->auth_key = $auth_key;
        $model->password = $password;
        $model->confirm_password= md5($post["confirm_password"]);  /// add  this line
        $model->registration_ip = $registration_ip;
        $model->created_at = $created_at;

but first name and last name and email id are required so it will throw validation error , to check this error use

$model->load();
$model->validate();
var_dump($model->errors);

it will show you the error . correct that errors then model will get save. you can solve that error using Scenario or

$model->saveAttributes('favorite_book'=>$model->favorite_book,'favorite_movie'=>$model->favorite_movie);

I hope it will help you.

Amitesh Kumar
  • 2,903
  • 22
  • 39