Laravel полиморфное отношение в Nova - PullRequest
0 голосов
/ 27 августа 2018

В моем текущем приложении, похожем на блог, Page может иметь множество Paragraphs различной структуры (текст, изображение, загрузка файла, форма регистрации и т. Д.). При попытке перевести это на Eloquent Models с отношениями, я думаю, что это простой способ сделать это:

Таблица pages:

  • ID
  • название, ...

Таблица paragraphs:

  • ID
  • page_id
  • paragraphable_id
  • paragraphable_type

Таблица paragraph_texts:

  • ID
  • текст

Таблица paragraph_images:

  • ID
  • image_path

Таблица paragraph_downloads:

  • ID
  • путь_к_файл

И модели:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Page extends Model
{

    public function paragraphs() {
        return $this->hasMany(Paragraph::class);
    }
}

?>

Модель абзаца:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Paragraph extends Model
{
    public $table = 'paragraphs';
    public $timestamps = [];

    public function page() {
        return $this->belongsTo(Page::class);
    }

    public function paragraphable() {
        return $this->morphTo();
    }
}

Модель типа текста в качестве образца:

<?php

namespace App\Models\ParagraphTypes;


use Illuminate\Database\Eloquent\Model;

class Text extends Model
{
    protected $table = 'paragraph_texts';

    public function paragraph() {
        return $this->morphOne(Paragraph::class, 'paragraphable');
    }

}

Теперь я хочу просмотреть страницу в nova и создать новый абзац по выбору типа. Я создал классы Resource (для страницы, для абзаца и для каждого типа абзаца) в соответствии с красноречивыми связями (поле HasMany для страницы, MorphTo для абзаца и просто TextArea для типа Text). Когда я вижу детали страницы и хочу добавить новый абзац, я вижу форму для добавления абзаца и могу выбрать тип абзаца в раскрывающемся списке, но вижу только уже существующие записи, но не новые. Я никогда не захочу добавить существующий тип абзаца, как этот.

Итак, вопросы:

  • Является ли преобразование структуры в красноречивое правильно, есть ли улучшения?
  • Как laravel nova может справиться с созданием нового типа абзаца для страницы "через" модель абзаца? Я чувствую, что для этого нужно добавить настраиваемое поле, которое, возможно, запрашивает тип для создания в первую очередь ...

1 Ответ

0 голосов
/ 27 августа 2018

Относительно вашего первого вопроса: вы должны использовать отношения из документации :

class Page extends Model
{
    public function texts() {
        return $this->morphedByMany(Text::class, 'paragraphable', 'paragraphs');
    }
}

class Text extends Model
{
    public function pages() {
        return $this->morphToMany(Page::class, 'paragraphable', 'paragraphs');
    }
}

Вы можете получить несколько типов абзацев с помощью метода доступа:

class Page extends Model
{
    public function getParagraphsAttribute() {
        return $this->texts->toBase()->merge($this->files)->merge([...]);
    }
}

$paragraphs = $page->paragraphs;
...