Welcome Guest, Not a member yet? Register   Sign In
Inserting/Updating "Userstamps" from a Model
#1

I am beginning a new project in CI4 where one of the requirement is to track when a table row is created and/or updated by particular user.  This should behave like the CI4 Model's "created_at" and "updated_at" timestamp columns.  I have similarly created database columns called "created_by" and "updated_by" for each table.  It is simple enough to add these columns to the $allowedFields array and pass the user_id value from the session to the model using the controller, but that does not seem proper.  Ideally these fields should behave in a similar way to $createdField and $updatedField where the model automatically grabs the user_id value from the session and inserts or updates that value when appropriate.  I am relatively new to CodeIgniter and frameworks in general.  I am unsure of the best way to achieve this.  I'm hoping someone with more experience can point me in the right direction.  Thank you in advance.
Reply
#2

(This post was last modified: 08-31-2023, 09:21 PM by InsiteFX. Edit Reason: spelling error )

If you take a look at the Model Insert method you can see how CodeIgniter is doing this.

Take a look at the if statements.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

(08-19-2020, 04:22 AM)InsiteFX Wrote: If you take a look at the Model Insert method you can see how CodeIgniter is doing this.

Take a look ad the if statements.

InsiteFX, I followed your advice. Based on what I learned from looking at the CodeIgniter Model, I was able to come up with this:

PHP Code:
/**
     * This method saves the session "user_id" value to "created_by" and "updated_by" array 
     * elements before the row is inserted into the database.
     *
     */
    protected function insertUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && 
            !array_key_exists('created_by'$data) && !array_key_exists('updated_by'$data)) {
            $data['data']['created_by'] = $user_id;
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    }

    /**
     * This method saves the session "user_id" value to "updated_by" array element before 
     * the row is inserted into the database.
     *
     */
    protected function updateUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && !array_key_exists('updated_by'$data)) {
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    

I then included them in the $beforeInsert and $beforeUpdate arrays.  Everything seems to be working correctly.

I do have one followup question.  What is the best way to make these methods available to every model in App\Models?  Should I create a new "CustomModel" that extends Model with these methods, and make all models located in App\Models children of the new custom model?
Reply
#4

(08-27-2020, 08:41 AM)mlurie Wrote:
(08-19-2020, 04:22 AM)InsiteFX Wrote: If you take a look at the Model Insert method you can see how CodeIgniter is doing this.

Take a look ad the if statements.

InsiteFX, I followed your advice. Based on what I learned from looking at the CodeIgniter Model, I was able to come up with this:

PHP Code:
   /**
     * This method saves the session "user_id" value to "created_by" and "updated_by" array 
     * elements before the row is inserted into the database.
     *
     */
    protected function insertUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && 
            !array_key_exists('created_by'$data) && !array_key_exists('updated_by'$data)) {
            $data['data']['created_by'] = $user_id;
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    }

    /**
     * This method saves the session "user_id" value to "updated_by" array element before 
     * the row is inserted into the database.
     *
     */
    protected function updateUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && !array_key_exists('updated_by'$data)) {
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    

I then included them in the $beforeInsert and $beforeUpdate arrays.  Everything seems to be working correctly.

I do have one followup question.  What is the best way to make these methods available to every model in App\Models?  Should I create a new "CustomModel" that extends Model with these methods, and make all models located in App\Models children of the new custom model?

Creating a new "CustomModel" that extends Model with these methods, and making all models located in App\Models children of the new custom model accomplished my goal.
Reply
#5

Glad to here you got it working.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#6

(This post was last modified: 12-19-2020, 02:36 AM by Matleyx.)

Hi Mlurie.
I'm interest for this functionality.
Can you explain me how you add this?
I understand that you created a new model, but if you tell me all the steps, i'll thank you a lot.
Reply
#7

(This post was last modified: 12-19-2020, 01:50 PM by InsiteFX.)

Just create a new model that extends CodeIgniter's Model.

PHP Code:
?php

namespace App\Models;

use 
CodeIgniter\Model;


class 
YourModelName extends Model
{
    
/**
     * Class properties go here.
     * -------------------------------------------------------------------
     *
     * public, private, protected, static and const.
     */


    /**
     * Name of database table
     *
     * @var string
     */
    
protected $table '';

    
/**
     * The format that the results should be returned as.
     * Will be overridden if the as* methods are used.
     *
     * @var string
     */
    
protected $returnType 'array';


    
/**
     * An array of field names that are allowed
     * to be set by the user in inserts/updates.
     *
     * @var array
     */
    
protected $allowedFields = [];

    
/**
     * __construct ()
     * -------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    
public function __construct()
    {
        
parent::__construct();
    }

    
// -----------------------------------------------------------------------

}   // End of YourModelName Model Class.

/**
 * -----------------------------------------------------------------------
 * Filename: YourModelName.php
 * Location: ./app/Models/YourModelName.php
 * -----------------------------------------------------------------------
 */ 

Just add his code from above to this Model that you should rename to your Model's name.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#8

ok, ho creato questo CustomModel.php:
PHP Code:
<?php

namespace App\Models;

use 
CodeIgniter\Model;


class 
CustomModel extends Model
{
    /**
     * Class properties go here.
     * -------------------------------------------------------------------
     *
     * public, private, protected, static and const.
     */


    /**
     * Name of database table
     *
     * @var string
     */
    protected $table '';

    /**
     * The format that the results should be returned as.
     * Will be overridden if the as* methods are used.
     *
     * @var string
     */
    protected $returnType 'array';


    /**
     * An array of field names that are allowed
     * to be set by the user in inserts/updates.
     *
     * @var array
     */
    protected $allowedFields = [];

    /**
     * __construct ()
     * -------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    public function __construct()
    {
        parent::__construct();
    }

    // -----------------------------------------------------------------------
  /**
     * This method saves the session "user_id" value to "created_by" and "updated_by" array 
     * elements before the row is inserted into the database.
     *
     */
    protected function insertUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && 
            !array_key_exists('created_by'$data) && !array_key_exists('updated_by'$data)) {
            $data['data']['created_by'] = $user_id;
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    }

    /**
     * This method saves the session "user_id" value to "updated_by" array element before 
     * the row is inserted into the database.
     *
     */
    protected function updateUserstamp(array $data) {
        $user_id session()->get('user_id');
        if (!empty($user_id) && !array_key_exists('updated_by'$data)) {
            $data['data']['updated_by'] = $user_id;
        }
        return $data;
    
}
   // End of YourModelName Model Class.

/**
 * -----------------------------------------------------------------------
 * Filename: YourModelName.php
 * Location: ./app/Models/YourModelName.php
 * -----------------------------------------------------------------------
 */ 


But do I also have to modify the standard model to run these functions?
Otherwise how do I call them in insert and updates?
Reply
#9

You include the method names that you created into the $beforeInsert and $beforeUpdate arrays.  


PHP Code:
/**
 * Callbacks for beforeInsert
 *
 * @var array
 */
protected $beforeInsert = [
    'insertUserstamp',
];

/**
 * Callbacks for afterUpdate
 *
 * @var array
 */
protected $afterUpdate = [
    'updateUserstamp',
]; 

What this is doing is using your new methods as callback methods.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#10

Create a new custom model with the above functions that extends the CodeIgniter Model. Then in all of your other models, you will extend this new custom model instead of extending the CodeIgniter model. Your models will inherit the methods from the custom model as well as the CodeIgniter Model.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB