Laravel Datatable связь ManyToMany с несколькими таблицами - PullRequest
7 голосов
/ 31 мая 2019

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

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

Database schema

Ответы [ 3 ]

2 голосов
/ 06 июня 2019

Вот как я бы это сделал,

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

}

Это должно дать вам массив объектов всего.Вы можете использовать сводную таблицу, но мне нравится этот способ.

0 голосов
/ 03 июня 2019

Вы не следовали стандартному соглашению об именах, поэтому вам необходимо явно передать соответствующие ключи и имена таблиц.

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');
    }
}
0 голосов
/ 03 июня 2019

Полагаю, 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');
    }

    //...
}

И последняя модель - это отношения OfferCountries и offers.Мы должны предоставить 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...