Autodesk
Autodesk

Reputation: 711

Override Eloquent Relation Create Method

I want to override create method, but with relation, it didn't touch the create method.

There are Two Models:

class User extends Model
{
    public function user_detail()
    {
        return $this->hasOne(UserDetail::class);
    }
}


class UserDetail extends Model
{
    public static function create(array $attributes = [])
    {
        //I was trying to do something like
        /*
        if(isset($attributes['last_name']) && isset($attributes['first_name']))
        {
            $attributes['full_name']=$attributes['first_name'].' '.$attributes['last_name'];
        }
        unset($attributes['first_name'],$attributes['last_name']);
        */

        Log::debug('create:',$attributes);
        $model = static::query()->create($attributes);
        return $model;
    }
}

When I use UserDetail::create($validated), and there is a log in laravel.log, so I know the code touched my custom create method.

But if I use

$user = User::create($validated);
$user->user_detail()->create($validated);

There is no log in laravel.log, which means laravel didn't touch the create method, then how I supposed to do to override create method under this circumstance?(I'm using laravel 5.7)

Upvotes: 0

Views: 912

Answers (1)

Autodesk
Autodesk

Reputation: 711

Thank you @Jonas Staudenmeir, after I read the documentation, here is my solution.

If the $attributes are not in protected $fillable array, then I do it in the __construct method.

class UserDetail extends Model
{
    protected $fillable=['full_name','updated_ip','created_ip'];

    public function __construct(array $attributes = [])
    {
        if (isset($attributes['first_name']) && isset($attributes['last_name'])) {
            $attributes['full_name'] = $attributes['first_name'].' '.$attributes['last_name'];
        }

        parent::__construct($attributes);
    }
}

Otherwise, I do it in Observer.

namespace App\Observers;

use App\Models\UserDetail;

class UserDetailObserver
{
    public function creating(UserDetail $userDetail)
    {
        $userDetail->created_ip = request()->ip();
    }

    public function updating(UserDetail $userDetail)
    {
        $userDetail->updated_ip = request()->ip();
    }

}

Register Observer in AppServiceProvider.

namespace App\Providers;

use App\Models\UserDetail;

use App\Observers\UserDetailObserver;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        UserDetail::observe(UserDetailObserver::class);
    }
}

I choose Observer instead of Event&Listener is for easy maintenance.

Upvotes: 1

Related Questions