Feat: Add `Article` and `Author` Models and migrations
The `Author` model relates to the pre-defined `User` model and the two new models relate to each other as expected.
This commit is contained in:
parent
229caa9614
commit
b1fb5f09b7
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/** The name of the database table storing this Model's records. */
|
||||
protected string $table = 'articles';
|
||||
|
||||
/** The attributes on the Model that can be mass-assigned */
|
||||
protected array $fillable = [
|
||||
'title',
|
||||
'subtitle',
|
||||
'author_id',
|
||||
'slug',
|
||||
'body',
|
||||
'published_at',
|
||||
'header_image_url',
|
||||
'path_to_markdown_source',
|
||||
'processed_at',
|
||||
];
|
||||
|
||||
/** The person that wrote the article. */
|
||||
public function author(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Author::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Author extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/** The name of the database table storing this Model's records. */
|
||||
protected string $table = 'authors';
|
||||
|
||||
/** The attributes on the Model that can be mass-assigned */
|
||||
protected array $fillable = [
|
||||
'display_name',
|
||||
'profile_image_url',
|
||||
'user_id',
|
||||
'biography',
|
||||
'primary_link',
|
||||
'secondary_link',
|
||||
'mastodon_handle',
|
||||
];
|
||||
|
||||
/** The application-level User account of this writer */
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(User::class);
|
||||
}
|
||||
|
||||
/** All the Articles this person has written */
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(Article::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('articles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->string('title', 255);
|
||||
|
||||
// The URL-encoded version of the title, more or less. Also acts as
|
||||
// the unique, public-facing identifier for the article
|
||||
$table->string('slug', 255);
|
||||
|
||||
$table->foreignId('author_id')
|
||||
->constrained(table: 'authors', indexName: 'articles_authors_id')
|
||||
->onUpdate('cascade')
|
||||
->onDelete('cascade');
|
||||
|
||||
$table->string('subtitle', 255)->nullable();
|
||||
|
||||
// The HTML-formatted version of the body, ready for browser display
|
||||
$table->longText('body');
|
||||
|
||||
// The dateTime when the article was made public to the world. If
|
||||
// it's in the future or doesn't exist, the article hasn't been
|
||||
// published yet
|
||||
$table->dateTime('published_at')->nullable();
|
||||
|
||||
$table->string('header_image_url', 255)->nullable();
|
||||
|
||||
// The path on the server disk to the original markdown file.
|
||||
$table->string('path_to_markdown_source');
|
||||
|
||||
// The dateTime when the original markdown file was parsed and the
|
||||
// HTML body was generated (among other things)
|
||||
$table->dateTime('processed_at')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('articles');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('authors', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
// Since we're separating authors and Word Salad User's as entities, this will strictly control how their
|
||||
// name appears in authorial contexts.
|
||||
$table->string('display_name', 100);
|
||||
|
||||
// The link the author's profile picture
|
||||
$table->string('profile_image_url')->nullable();
|
||||
|
||||
$table->foreignId('user_id')
|
||||
->constrained(table: 'users', indexName: 'authors_user_id')
|
||||
->onUpdate('cascade')
|
||||
->onDelete('cascade')
|
||||
->nullable();
|
||||
|
||||
// An introductory paragraph or two of the author
|
||||
$table->text('biography')->nullable();
|
||||
|
||||
// A URL to the author's primary home on the web, a special shout out, whatever
|
||||
$table->string('primary_link', 120)->nullable();
|
||||
$table->string('secondary_link', 120)->nullable();
|
||||
|
||||
$table->string('mastodon_handle', 200)->nullable();
|
||||
|
||||
// created_at and updated_at timestamps
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('authors');
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue