跨包的Laravel模型关系

时间:2018-10-08 17:31:18

标签: php laravel composer-php

我正在尝试重构项目,以免将App文件夹下的所有代码放入单独的作曲家程序包中。但是我遇到了一个障碍,可以使用一些输入来解决:

为简化起见,我想创建2个软件包,CoreCustomers。我希望Core完全分开,不引用任何其他软件包。在Core内部有一个名为Business的模型,在Customer中有一个名为Customer的模型。这些模型之间存在多对一的关系。当我要创建雄辩的关系方法时,就会出现问题。 Customer依赖于Core,因此这不是问题,$this->belongsTo(Business::class)。但是,要求逆Core,需要了解Customer模型$this->hasMany(Customer::class)

有没有解决的办法?像是从我的Business包中在Customer模型上注册方法一样?还是我倒退了?

编辑

对于不熟悉Laravel的人,在模型类中将关系定义为函数

class Business extends Model {
   public function customers() {
       return $this->hasMany(Customer::class);
   }
}

2 个答案:

答案 0 :(得分:0)

大多数人这样做是依赖注入,但这更多是服务类型的事情,而不是模型关系类型的事情。现在,您可以想到几个选择。

  1. 将Business类从核心移出,或将客户移到核心。这取决于这些模型对您的应用程序有多“核心”。
  2. 依赖性使用枚举或注册表来注入您的关系

       class Business extends Model {
           public function customers() {
               return $this->hasMany(ModelEnum::byName('Customers')->class());
           }
       }
    

 class Business extends Model {
       public function customers() {
           $models = collect(get_declared_classes())->filter(function ($item) {
               $item == 'YOURPACKAGENAME\Models\\Customers' ? $item : throw new Exception();

               return $item
           });

           return $this->hasMany($item);
       }
    }

我认为最好的办法是添加或删除类,而拥有内部包模型则无法达到用包将代码分开的目的。

答案 1 :(得分:0)

两种可能的解决方案:

  1. 直接声明关系,如果类不存在则抛出异常:

    public function customers() {
        if (class_exists(Customer::class)) {
            throw new \SomeException();
        }
    
        return $this->hasMany(Customer::class);
    }
    

    ::class不会触发自动加载,因此即使没有可用的类也可以使用它。这仍然会建立对Customers的依赖关系,但至少它是可选的。

  2. Customers程序包可以为Business提供适当的关系。因此,如果要将Business类与Customers一起使用,则应使用Customers\Models\Business而不是Core\Models\Business

    class Business extends \Core\Models\Business {
    
        public function customers() {
            return $this->hasMany(Customer::class);
        }
    }
    

    这将使Core摆脱对Customers的依赖,但是它根本无法扩展(您不能拥有与Business类相同的第二个软件包)。