My current blog like app has a Page that could have many Paragraphs of a different structure (Text, Image, File download, Registration form, ... ). When trying to translate this to Eloquent Models with relations, I think this is an easy way to do so:
Table pages:
- id
- title, ...
Table paragraphs:
- id
- page_id
- paragraphable_id
- paragraphable_type
Table paragraph_texts:
- id
- text
Table paragraph_images:
- id
- image_path
Table paragraph_downloads:
- id
- file_path
And the Models:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Page extends Model
{
public function paragraphs() {
return $this->hasMany(Paragraph::class);
}
}
?>
The Paragraph Model:
<?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();
}
}
The Text Type model as sample:
<?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');
}
}
I now want to view the page in nova and create a new paragraph by a selectable type. I created the Resource classes (for page, for paragraph and for each paragraph type) according to the eloquent relations (HasMany field for the page, MorphTo for the paragraph and just a TextArea for the Text type). When I see the details of a page and want to add a new paragraph, I can see the form to add a paragraph and can select the paragraph type in a dropdown but can only see the already existing entries, not new one. I will never want to add an existing paragraph type like this.
So questions:
- Is the transformation of the structure into eloquent correct, are there any improvements?
- How could laravel nova handle the creation of a new paragraph type for a page "through" the paragraph model? I feel like having to add a custom field to do so, that maybe asks for the type to create first...