覆盖口才关系创建方法

时间:2019-01-05 15:05:31

标签: laravel-5 eloquent

我想覆盖create方法,但与关系无关,它没有触及create方法。

有两种型号:

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;
    }
}

当我使用UserDetail::create($validated)时,laravel.log中有一个日志,因此我知道代码触及了我的自定义创建方法。

但是如果我使用

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

laravel.log中没有日志,这意味着laravel没有接触过create方法,那么在这种情况下我应该怎么做来覆盖create方法?(我使用的是laravel 5.7)

1 个答案:

答案 0 :(得分:0)

谢谢@Jonas Staudenmeir,在阅读文档之后,这是我的解决方案。

如果$ 属性 不在受保护的$ fillable数组中,那么我可以使用__construct方法。

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);
    }
}

否则,我会在《观察家》中这样做。

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();
    }

}

在AppServiceProvider中注册观察者。

namespace App\Providers;

use App\Models\UserDetail;

use App\Observers\UserDetailObserver;

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

我选择Observer而不是Event&Listener是为了易于维护。