Laravel Полиморфные отношения получают смешанную коллекцию - PullRequest
0 голосов
/ 23 января 2019

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

page
    - id
    - title

block1
    - id
    - title

block2
    - id
    - title

page_blocks
    - id
    - page_id
    - block_id
    - block_type
    - weight

Внутри страницы я определил 2 полиморфных отношения, которые позволяют мне связывать блоки со страницей следующим образом:

Class Page extends Model {
        ....

        public function block1() {
            return $this->morphedByMany('App\Models\Block1', 'block', 'page_blocks', 'page_id');
        }

        public function block2() {
            return $this->morphedByMany('App\Models\Block2', 'block', 'page_blocks', 'page_id');
        }
}

Итак, теперьЯ могу добавить блоки на страницу, но мне нужно использовать правильные отношения для каждого блока.Например, я могу создать страницу, подобную этой:

$page = \App\Models\Page::firstOrCreate(['id' => 1], ['title' => 'Test']);

$block1 = \App\Models\Block1::firstOrCreate(['id' => 1], ['title' => 'Block 1 title']);
$block1_1 = \App\Models\Block1::firstOrCreate(['id' => 2], ['title' => 'Block 1.1 title']);
$block2 = \App\Models\Block2::firstOrCreate(['id' => 1], ['title' => 'Block 2 title']);

$page->block1()->sync([$block1->id => ['weight' => 1], $block1_1->id => ['weight' => 3]]);
$page->block2()->sync([$block2->id => ['weight' => 2]]);

В этом случае я хочу иметь следующий макет: элемент типа «Блок 1», затем элемент типа «Блок 2», за которым следуетдругой элемент типа «Блок1».

Если я хочу получить блоки, я могу выбрать их по отдельности, набрав такой тип:

$page = \App\Models\Page::with(['block1','block2'])->find(1);

Мне было интересно, есть ли способ получитьвсе блоки через полиморфные отношения и получить смешанную коллекцию предметов Block1 и Block2 в порядке веса

1 Ответ

0 голосов
/ 23 января 2019

После того, как вы используете оба блока:

$page = \App\Models\Page::with(['block1','block2'])->find(1);

Вы можете просто использовать функции сбора для их объединения и упорядочить:

$blocks = $page->block1->concat($page->block2)
                       ->sortBy('weight');

Вы можете узнать больше о методе concatздесь: https://laravel.com/docs/5.7/collections#method-concat.

...