Laravel - 多重启动覆盖

Cru*_*tie 3 php laravel eloquent laravel-5

在我的 laravel 项目中,我想使用一个特征来使用 anuuid作为主键并进行级联删除。

有 2 种型号:UserBox

一个user可以有很多Box,一个也Box可以有很多Box。因为我使用mysql,所以onDelete('cascade')不起作用,但我需要它。

所以我重写了Boot模型的方法来强制它,但是现在,我的特征(UuidIdentifiable)的Boot方法无法被调用。

uuid此特征的用途是在我创建新模型时生成主键。

现在,当我想创建一个模型时,当 Eloquent 插入值时,数据库返回一个错误,因为Id我的模型为 null。

因此,覆盖Boot模型上的 应该覆盖特征的 ,但是如何获得我的特征和模型的Boot自定义方法的功能呢?Boot

<!-- language: php -->
class Box extends Model
{
    use UuidIdentifiable;

    protected $fillable = ['label', 'parent_box_id', 'user_id'];
    protected $guarded = [];
    public $incrementing = false;

    public function owner() {
        return $this->belongsTo('App\User', 'user_id');
    }

    public function parent() {
        return $this->belongsTo('App\Box', 'parent_box_id');
    }

    public function boxes (){
        return $this->hasMany('App\box', 'parent_box_id', 'id');
    }

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

        static::deleting(function(Box $box) {
            $box->boxes()->delete();
        });
    }
}

class User extends Authenticatable
{
    use Notifiable, UuidIdentifiable;
    public $incrementing = false;

    protected $fillable = ['username', 'email', 'password'];

    protected $hidden = ['password', 'remember_token'];

    public function boxes (){
        return $this->hasMany('App\box', 'user_id', 'id');
    }

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

        static::deleting(function(User $user) {
            $user->boxes()->delete();
        });
    }
}

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

        static::creating(function ($model) {
            $model->{$model->getKeyName()} = Uuid::generate()->string;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

mos*_*znv 5

只需使用这个技巧:

namespace App\Traits;

trait UuidIdentifiable
{
    protected static function bootUuidIdentifiable()
    {
        static::creating(function ($model) {
            $model->{$model->getKeyName()} = Uuid::generate()->string;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您更改boot为该模型bootYourTraitName并启动功能,我认为您的问题将会解决。remove

最佳实践是将特征写入单独的文件中并仅在模型中使用它们。最好不要在模型中创建启动函数。


概括:

  1. app使用此名称在文件夹中创建一个目录:Traits
  2. app/Traits使用此名称创建一个文件:UuidIdentifiable
  3. 写出你自己的特点。请注意,您应该使用以下语法命名您的引导函数:bootYourTraitName
  4. 在您想要的每个模型中使用特征。