问题
When using Laravel 5.1, I am trying to create an Observer that will automatically update the following 3 columns
- created_by: populate when the record in created "never update this again"
- modified_by: populate a new value every time a record is modified
- 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?
回答1:
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
}
}
Hope this helps!
回答2:
I suggest you to use venturecraft revisionable package with this upgrade https://github.com/fico7489/laravel-revisionable-upgrade
Everything will work out of the box, you just need to use 2 traits, you can do much more that get info who edited model, you can get info who edited particular column, even particular value and much more...
回答3:
step 1: make trait
namespace App\Traits;
use App\Observer\ModelObserver;
trait ObservantTrait
{
public static function bootObservantTrait()
{
static::observe(ModelObserver::class);
}
}
step 2: make observer
<?php
namespace App\Observer;
use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Config\Repository;
use Request;
class ModelObserver
{
public $userID;
protected $auth;
protected $login_user;
protected $ip;
protected $user_agent;
public function __construct(AuthManager $auth, Repository $config)
{
$this->auth = $auth;
$this->login_user = $auth->guard($this->auth->getDefaultDriver())->user();
if (isset($this->login_user->id)) {
$this->userID = $this->login_user->id;
$this->ip = Request::ip();
$this->user_agent = Request::header('user-agent');
}
}
public function updating($model)
{
$model->updated_by = $this->userID;
$model->ip = Request::ip();
$model->user_agent = Request::header('user-agent');
}
public function creating($model)
{
$model->created_by = $this->userID;
$model->ip = Request::ip();
$model->user_agent = Request::header('user-agent');
}
public function deleted($model)
{
$model->deleted_by = $this->userID;
$model->ip = Request::ip();
$model->user_agent = Request::header('user-agent');
$model->save();
}
}
step 3: user trait in model
use ObservantTrait;
来源:https://stackoverflow.com/questions/31709390/how-to-populate-the-modified-by-with-the-user-id-of-who-made-the-update-to-the-r