Laravel Datatable 与多个表的多对多关系

Posted

技术标签:

【中文标题】Laravel Datatable 与多个表的多对多关系【英文标题】:Laravel Datatable ManyToMany relationship with multiple tables 【发布时间】:2019-10-16 19:19:51 【问题描述】:

Offer.php #model

use App\OfferCategory;
use App\OfferCountries;
use App\OfferCreative;
use App\OfferTools;
use App\OfferTraffic;

class Offer extends Model 
public function offer_countries() 
    return $this->belongsToMany(OfferCountries::class);


public function offer_categories() 
    return $this->belongsToMany(OfferCategory::class);


public function offer_creatives() 
    return $this->hasMany(OfferCreative::class);


public function offer_tools() 
    return $this->hasMany(OfferTools::class);


public function offer_traffic() 
    return $this->hasMany(OfferTraffic::class);


public function platforms() 
    return $this->hasMany(Platform::class);

OfferController.php

 public function getMediaData() 
//        $model = Offer::with('offer_traffic');
//        return DataTables::eloquent($model)
//                        ->addColumn('traffic', function (Offer $user) 
//                            return $user->offer_traffic->map(function($post) 
//                                        return str_limit($post->allowed_traffic, 30, '...');
//                                    )->implode('<br>');
//                        )
//                        ->toJson();

        return datatables(DB::table('offers'))->toJson();
    

我想使用 offer.php 中给出的所有关系表和数据表中的图像。我已经尝试在控制器中使用注释代码,但无法获取请帮助我知道我做错了什么。

OfferCountries.php #model

使用应用\优惠;

class OfferCountries extends Model 

   function offers() 
         return $this->belongsToMany(Offer::class);
    

【问题讨论】:

检查此文档...laravel.com/docs/5.8/… 【参考方案1】:

我会这样做,

在 Offer.php 中

 class Offer extends Model 
    public function offer_countries() 
        return $this->hasMany(OfferOfferCountries::class,'offer_id','id');
    

    public function offer_categories() 
        return $this->hasMany(OfferOfferCategories::class,'offer_id','id');
    

    public function offer_creatives() 
        return $this->hasMany(OfferCreative::class,'offer_id','id');
    

    public function offer_tools() 
        return $this->hasMany(OfferTools::class,'offer_id','id');
    

    public function offer_traffic() 
        return $this->hasMany(OfferTraffic::class,'offer_id','id');
    

    public function platforms() 
        return $this->hasMany(Platform::class,'offer_id','id');
    
  

在 OfferOfferCountries.php 中

class OfferOfferCountries extends Model 
   public function countryDetail()
     return $this->belongsTo(OfferCountries::class,'offercountry_id','id');
   

在 OfferOfferCategory.php 中

class OfferOfferCategory extends Model 
   public function categoryDetail()
     return $this->belongsTo(OfferCategory::class,'offercategory_id','id');
   

现在在控制器中

public function getMediaData() 
        $data = Offer::with('offer_countries.countryDetail','offer_categories.categoryDetail','offer_creatives','offer_tools','offer_traffic','platforms')->get();

echo '<pre>';
print_r($data);


这应该为您提供所有对象的数组。您可以使用数据透视表,但我喜欢这种方式。

【讨论】:

谢谢你能帮忙处理数据表我收到错误允许的内存大小为 134217728 字节已用尽(试图分配 4096 字节) 好像代码某处有错误,很可能进入死循环。如果没有看到代码,就无法判断是什么导致了问题。如果这个答案解决了你的问题,你可以通过接受答案来结束这个问题【参考方案2】:

我想 Laravel 不能自动处理你的关系,因为你的数据库中的关系字段不标准(offer_id 在很多情况下,而不是默认的主键)

要解决此问题,您必须手动提供必须在其之上构建关系的字段名称。

Offer.php

class Offer extends Model

    public function offer_countries()
    
        // Here we provide parent key field name (offer_id) because we don't want to use the primary key for that
        return $this->belongsToMany(OfferCountries::class, null, null, null, 'offer_id');
    

    public function offer_categories()
    
        return $this->belongsToMany(OfferCategory::class, null, null, null, 'offer_id');
    

    public function offer_tools()
    
        // Map foreign key to local one 
        return $this->hasMany(OfferTools::class, 'offer_id', 'offer_id');
    

    public function offer_traffic()
    
        return $this->hasMany(OfferTraffic::class, 'offer_id', 'offer_id');
    

    //...

最后一个模型是OfferCountriesoffers 关系。我们必须提供relatedKey 参数来告诉 Eloquent 在哪个字段中查找外键:

OfferCountries.php

class OfferCountries extends Model

    function offers()
    
        return $this->belongsToMany(Offer::class, null, null, null, null, 'offer_id');
    


相关文档:

https://laravel.com/docs/5.8/eloquent-relationships#one-to-many

https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

【讨论】:

【参考方案3】:

您没有遵循标准命名约定,因此您必须明确传递那些相关的键和表名。

Offer.php

use App\OfferCategory;
use App\OfferCountries;
use App\OfferCreative;
use App\OfferTools;
use App\OfferTraffic;

class Offer extends Model 
 public function offer_countries() 
     return $this->belongsToMany(OfferCountries::class, 'offer_offer_countires', 'offer_id', 'offer_countries_id');
 

 public function offer_categories() 
     return $this->belongsToMany(OfferCategory::class, 'offer_offer_categories', 'offer_id', 'offer_category_id');
 

 public function offer_creatives() 
     return $this->hasMany(OfferCreative::class, 'offer_id');
 

 public function offer_tools() 
     return $this->hasMany(OfferTools::class, 'offer_id');
 

 public function offer_traffic() 
     return $this->hasMany(OfferTraffic::class, 'offer_id');
 

 public function platforms() 
     return $this->hasMany(Platform::class, 'offer_id');
 

OfferCountries.php

use App\Offer;

class OfferCountries extends Model 

   function offers() 
         return $this->belongsToMany(Offer::class, 'offer_offer_countires', 'offer_countries_id', 'offer_id');
    

【讨论】:

以上是关于Laravel Datatable 与多个表的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 与 uuid 的多对多关系返回总是空的

Laravel 定义同一张表的多对多关系

Laravel 多列上的多对多同步()

Laravel 与渴望的多对多关系

如何在Laravel中的多对多关系中添加“别名”?

为啥我的多对一 laravel 关系不起作用?