laravel 如何在文件夹中创建与不同模型的hasMany关系?

pepwfjgg  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(136)

我有一个奇怪的Laravel 9设置,由于被限制在一个非常古老的数据库。
我试图找到一种简洁的方法来创建一个文件夹中多个模型的hasMany关系,我相信用图表来解释会更容易:

app/Models/
- Customer
app/Models/Records/
- Orange
- Green
- Blue

现在,所有这些记录都与客户有某种联系,但它们也都不同,例如,橙子表示使用cid的客户,而绿色可能使用customerid
我已经设置了逻辑,其中每个记录模型都具有取决于不同字段名称的customer belongsTo关系。

public function customer()
    {
        return $this->belongsTo('App\Models\Customer', 'CustomerId');
    }

我需要在Customer模型中创建一个records()函数,该函数将所有这些找到的记录拉入,但我无法创建任何存储在DB中的新表。

3htmauhk

3htmauhk1#

要像hasMany那样连接多个表(模型),在Laravel中可能无法开箱即用。
不过,如果你真的需要把它们都结合起来,我做过一次,但并不漂亮。
首先将以下内容添加到示例中的每个App\Records\Model(绿色)

class Green extends Model
{
   protected $table = 'GreenRecords';

   ....
   ....

   // this is to append/add extra fields into your model
   // that not exist inside the table it self
   protected $appends = [
        'product_data',
        'stuffs',
   ];

   // relationship to App\Models\Customer
   public function customer()
   {
        return $this->belongsTo(Customer::class, 'customerid', 'id');
   }

   // you can use it later as Green::query()->customer($id)->get()
   public function scopeCustomer($query, $id)
   {
        return $query->where('customerid', $id);
   }
   
   // you can add here as many data as you like from table GreenRecords, 
   // this will make Green Orange and Blue as if they have common fields
   // you can also separate them by adding add each custom field to $appends
   public function getProductDataAttribute()
   {
        return [
           'name' => $this->name,
           'color' => $this->color,
           'stuffs' => $this->stuffs,
           'other_stuffs' => $this->other_stuffs,
        ];
   }
   public function getStuffsAttribute()
   {
        return $this->stuffs;
   }
   
}

现在是客户模型

class Customer extends Model
{
    // your Customer relation to Orange
    public function oranges()
    {
       return $this->hasMany(Orange::class, 'cid', 'id');
    }

    // your Customer relation to Green
    public function greens()
    {
       return $this->hasMany(Green::class, 'customerid', 'id');
    }

    public function getRecords(): Collection
    {
       // we can not use collection merge due to same 'id' in Orange and Green
       $collections = collect();

       if ($oranges = Orange::query()
           ->customer($this->id)
           ->get()
       ) {
           foreach ($oranges as $record) {
               $collections->push($record);
           }
       }

       if ($greens = Green::query()
           ->customer($this->id)
           ->get()
        ) {
           foreach ($greens as $record) {
               $collections->push($record);
           }
       }

       return $collections;
    }
}

所以现在你可以

$customer = Customer::find(3);
$records = $customer->getRecords(); // result will be a collection

在刀片内部,您可以访问它们

@foreach ($records as $record) 
   {{ $record->stuffs }}
   {{ $records->product_data['other_stuffs'] }}
@endforeach

可以对集合进行筛选和排序

$records->where('product_data.stuffs', 'abc')->sortBy('name');

这里唯一的问题是记录id,其中橙色可以与绿色和蓝色具有相同的id。
最好是在橙绿和蓝$table->uuid('record_id')->nullable();中添加新字段
希望这能帮到你。

相关问题