Связь сводной модели Laravel с другой таблицей

#laravel #eloquent-relationship

#laravel #красноречивый-связь

Вопрос:

введите описание изображения здесь

Объяснение базы данных:

  • Элемент имеет много уровней
  • Уровень имеет один тип (размер, параметр ИЛИ дополнение)
  • тип имеет отношение «многие ко многим» с параметром
  • optionType имеет множество размеров и цен

Проблема: в запросе eloquent я могу извлекать данные до option_type, я не знаю, как создать связь сводной модели option_type с моделью размера.

Красноречивый запрос:

 $items = Item::with(['tiers' => function ($query) {
            $query->with(['type' => function($query) {
                $query->with('sizes')
                    ->with('options')
                    ->with('addons');
            }]);
        }])->where('id', 1)->get();
        return $items;
  

Чего я хочу достичь:
Я хочу с нетерпением загружать option_type с размерами, для каждой строки optiontype у меня может быть size и его цена.

Проблема: когда я пишу запрос, подобный:

 $query->with(['options' => function($query) {
    $query->with('sizes);
}])
  

В основном говорится, что параметры имеют отношение к размерам, что неверно, должно быть, optionType имеет отношение к размеру. как я могу получить данные, чтобы я мог показать мне для записи для каждого optiontype_id, size_id и price.

Тип модели:

 class Type extends Model
{
    protected $table = 'types';

    public function options()
    {
        return $this->belongsToMany(Option::class);
    }
}
  

Модель опций:

 class Option extends Model
{
    public function type()
    {
        return $this->belongsToMany(Type::class);
    }
}
  

Модель optionType:

 use IlluminateDatabaseEloquentRelationsPivot;

class OptionType extends Pivot
{
    protected $table = 'option_type';

    public function optiontypesize()
    {
        return $this->belongsToMany(Size::class, 'option_type_size', 'size_id', 'option_type_id');
    }
}
  

Модель размера:

 class Size extends Model
{
    public function optiontypesize()
    {
        return $this->belongsToMany(OptionType::class, 'option_type_size', 'size_id', 'option_type_id');
    }
}
  

Ответ №1:

Я сам решил проблему, я напишу подробный ответ здесь на случай, если кто-то столкнется с такой же проблемой в будущем.

Я изменил базу данных, но концепция проблемы осталась прежней.

введите описание изображения здесь

Объяснение:

  • элементы имеют много уровней
  • уровни имеют один тип
  • уровни имеют много опций, а параметры имеют много уровней (приведение таблицы option_tier в сцену)
  • option_tier имеет много размеров, а sizes имеет много option_tier (приведение таблицы option_tier_price в сцену с дополнительным полем «цена»)

Решения: я использую AjCastro EagerLoadPivotRelations EagerLoadPivotTrait для быстрой загрузки сводных отношений. Концепция взята из этой статьи https://medium.com/@ajcastro29/laravel-eloquent-eager-load-pivot-relations-dba579f3fd3a Единственная разница в том, что я изменил отношения с belongTo на hasMany на, и это работает как заклинание.

Модель уровня:

 use AjCastroEagerLoadPivotRelationsEagerLoadPivotTrait;

class Tier extends Model
{
    use EagerLoadPivotTrait;
    protected $table = 'tiers';

    public function options()
    {
        return $this->belongsToMany(Option::class, 'option_tier')
            ->using(OptionTier::class)
            ->withPivot('id');
    }
}
  

Модель опций:

 use AjCastroEagerLoadPivotRelationsEagerLoadPivotTrait;

class Option extends Model
{
    use EagerLoadPivotTrait;

    protected $table = 'options';
    
    public function tiers()
    {
        return $this->belongsToMany(Tier::class, 'option_tier');
    }
}
  

Модель на уровне опций:

 use AjCastroEagerLoadPivotRelationsEagerLoadPivotTrait;
use IlluminateDatabaseEloquentRelationsPivot;

class OptionTier extends Pivot
{
    use EagerLoadPivotTrait;
    
    protected $table = 'option_tier';
    
    public function price()
    {
        return $this->hasMany(OptionTierPrice::class, 'option_tier_id');
    }
}
  

Модель OptionTierPrice:

 use AjCastroEagerLoadPivotRelationsEagerLoadPivotTrait;

class OptionTierPrice extends Model
{
    use EagerLoadPivotTrait;
    
    protected $table = 'option_tier_price';
    
    public function size()
    {
        return $this->belongsTo(Size::class);
    }
}
  

Контроллер:

 $tiers = Product::with(['tiers' => function($query) {
    $query->with(['type'])
          ->with(['sizes'])
          ->with(['options.pivot.price.size'])
          ->with(['addons.pivot.price.size']);
}])
->get();
return $tiers;