Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to populate the modified_by with the user_id of who made the update to the record using laravel 5.1?

When using Laravel 5.1, I am trying to create an Observer that will automatically update the following 3 columns

  1. created_by: populate when the record in created "never update this again"
  2. modified_by: populate a new value every time a record is modified
  3. purged_by: populate a value when a record is soft deleted.

I understand that Eloquent will automatically update the date time stamp (created_by, updated_at, removed_at) but I need to update the user_id that made the change.

I was advised to use Observer and a trait to handle this. Here is what I have done

1) created an observer class called "ModelSignature" located in app\Observers\ModelSignature.php and this is it's content

<?php 

namespace App\Observers;

class ModelSignature {

    protected $userID;

    public function __construct(){
        $this->userID =  Auth::id();
    }


    public function updating($model)
    {
        $model->modified_by = $this->userID;
    }


    public function creating($model)
    {
        $model->created_by = $this->userID;
    }


    public function removing($model)
    {
        $model->purged_by = $this->userID;
    }

}

I then created a new Trait called "RecordSignature" located in app\Traits\RecordSignature.php and contains the following code

<?php

namespace App\Traits;

use app\Observers\ModelSignature;

trait RecordSignature
{

    public static function bootObservantTrait()
    {
        static::observe(new ModelSignature() );
    }
}

Finally, in my "Account" model located on "app\Models\Account.php" I use it like this

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\industry;
use App\Traits\RecordSignature;
use App\Traits\TrimScalarValues;


class Account extends Model
{
    use RecordSignature, TrimScalarValues;
    /**
     * The database table used by the model.
     *
     * @var string
    */
    protected $table = 'accounts';

    protected $primaryKey = 'account_id';

    const CREATED_AT = 'created_on';

    const UPDATED_AT = 'modified_on';

    const REMOVED_AT = 'purged_on';


    /**
     * The attributes that are mass assignable.
     *
     * @var array
    */
    protected $fillable = ['client_id','account_name', 'company_code', 'legal_name', 'created_by','modified_by','instrucations'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
    */
    //protected $hidden = ['account_id', 'remember_token'];


    protected $guarded = ['account_id'];

    /**
     * Get the industry record associated with the account.
    */
    public function industry()
    {
        return $this->hasOne(industry, industry::primaryKey);
    }

    public function pk(){

        return $this->primaryKey;
    }

}

The problem is that the methods updating(), removing() and creating() are not populating the userId as expected. It seems that the fields are being ignored or the methods are not being fired!

What am I doing wrong here?

like image 602
Junior Avatar asked Mar 16 '23 06:03

Junior


1 Answers

You should be able to get rid of your ModelSignatures Class and change your trait to something like:

trait RecordSignature
{
    protected static function boot()
    {
        parent::boot();

        static::updating(function ($model) {

            $model->modified_by = \Auth::User()->id;
        });

        static::creating(function ($model) {

            $model->created_by = \Auth::User()->id;
        });
        //etc

    }

}

Update:

There are many packages nowadays that will handle this sort of thing for you. One that I currently use quite a bit is Laravel Auditing which will not only keep track of who performed a task but also any changes to row as well.

like image 138
Rwd Avatar answered Mar 18 '23 05:03

Rwd