Как получить красноречивые отношения, используя родительское значение поворота как условие - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь получить отношение hasMany в Eloquent, но использую значение сводной таблицы родителя в предложении where.

Например,

class Page
{
    public function modules()
    {
        return $this->belongsToMany(Module::class)->withPivot('sun_id');
    }
}

class Module
{
    public function settings()
    {
        return $this->hasMany(ModuleSetting::class)
            ->where('sun_id', $this->pivot->sun_id);
    }
}

$page = Page::with('modules.settings')->get();

$this->pivot-sun_id inФункция «Настройки», очевидно, не работает.Как мне этого добиться?Нужно ли мне писать необработанный оператор БД, когда я объявляю $ page, или есть более "Eloquent-esque" метод?

Спасибо

Редактировать

Прилагается моя схема таблицы.enter image description here

  • страниц : Таблица не требует пояснений.Содержит список страниц
  • modules : Модули являются элементами страницы.Блок текста или календарь, например
  • module_page : сводная таблица для привязки модулей к странице
  • module_settings .Страница может иметь более одного модуля одного типа.Итак, два календаря, например.таблица настроек модуля определяет настройки для календаря, такие как цвет, если календарь загружается и т. д.

1 Ответ

1 голос
/ 12 июля 2019

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

К сожалению, я не верю, что можно строго выполнять то, что вы просите, с красноречивыми связями, потому что, как только вы попадете в модули, у вас не будет никакого способа достичьназад ", чтобы получить идентификатор страницы.

Вы заметите, что есть два метода withModuleSettings(), один для коллекции страниц и один для отдельной страницы.

Создайте новый файл:

App / PageCollection.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Collection;

class PageCollection extends Collection
{
    // this will load the module settings based on page id
    public function withModuleSettings()
    {
        foreach ($this as $p => $page) {
            $this[$p]->withModuleSettings();
        }

        return $this;
    }
}

Ваши модели:

class Page extends Model
{
    // ... 

    public function modules()
    {
        return $this->belongsToMany(Module::class)->withPivot('module_instance');
    }

    // override the default collection instance with our own
    public function newCollection(array $models = [])
    {
        return new PageCollection($models);
    }

    // this will load the module settings based on page id
    public function withModuleSettings()
    {
        // this page id
        $id = $this->id;

        foreach ($this->modules as $m => $module) {

            // get module instance from pivot
            $instance = $module->pivot->module_instance;

            // load relations
            $this->modules[$m]->load(['settings' => function($query) use ($id, $instance) {
                $query
                    ->where('module_settings.page_id',$id)
                    ->where('module_settings.module_instance',$instance)
                ;
            }]);
        }

        return $this;
    }
}

class Module extends Model
{
    // ...

    public function settings()
    {
        return $this->hasManyThrough(
            ModuleSetting::class,
            ModulePage::class,
            'module_id',         // first key
            'module_instance',   // second key
            'id',                // local key
            'module_instance'    // second local key
        );
    }
}

class ModulePage extends Model
{
    // define the table name since Laravel expects it to be 'module_pages'
    protected $table = 'module_page';
}

class ModuleSetting extends Model
{
    // ...
}

Действие:

$pages = Page::with('modules')->get()->withModuleSettings();

Работает и с отдельными страницами:

$page = Page::with('modules')->first()->withModuleSettings();
...