Skip to main content
Back to packages
436 GitHub stars

oddvalue/laravel-drafts

View on GitHub

Description

A simple, drop-in drafts/revisions system for Laravel models

Preparing your models

Add the trait

Add the HasDrafts trait to your model

<?php
 
use Illuminate\Database\Eloquent\Model;
use Oddvalue\LaravelDrafts\Concerns\HasDrafts;
 
class Post extends Model
{
use HasDrafts;
 
...
}

Relations

The package can handle basic relations to other models. When a draft is published HasOne and HasMany relations will be duplicated to the published model and BelongsToMany and MorphToMany relations will be synced to the published model. In order for this to happen you first need to set the $draftableRelations property on the model.

protected array $draftableRelations = [
'posts',
'tags',
];

Alternatively you may override the getDraftableRelations method.

public function getDraftableRelations()
{
return ['posts', 'tags'];
}

The API

The HasDrafts trait will add a default scope that will only return published/live records.

The following query builder methods are available to alter this behavior:

  • withoutDrafts()/published(bool $withoutDrafts = true) Only select published records (default)
  • withDrafts(bool $withDrafts = false) Include draft record
  • onlyDrafts() Select only drafts, exclude published

Creating a new record

By default, new records will be created as published. You can change this either by including 'is_published' => false in the attributes of the model or by using the createDraft or saveAsDraft methods.

Post::create([
'title' => 'Foo',
'is_published' => false,
]);
 
# OR
 
Post::createDraft(['title' => 'Foo']);
 
# OR
 
Post::make(['title' => 'Foo'])->saveAsDraft();

When saving/updating a record the published state will be maintained. If you want to save a draft of a published record then you can use the saveAsDraft and updateAsDraft methods.

# Create published post
$post = Post::create(['title' => 'Foo']);
 
# Create drafted copy
 
$post->updateAsDraft(['title' => 'Bar']);
 
# OR
 
$post->title = 'Bar';
$post->saveAsDraft();

This will create a draft record and the original record will be left unchanged.

# title uuid published_at is_published is_current created_at updated_at
1 Foo 9188eb5b-cc42-47e9-aec3-d396666b4e80 2000-01-01 00:00:00 1 0 2000-01-01 00:00:00 2000-01-01 00:00:00
2 Bar 9188eb5b-cc42-47e9-aec3-d396666b4e80 2000-01-02 00:00:00 0 1 2000-01-02 00:00:00 2000-01-02 00:00:00

Recent Courses on Laravel Daily

[NEW] Practical Laravel Security: Packages, Secrets, Supply-Chain Attacks

7 lessons
43 min read

Queues in Laravel 13

18 lessons
1 h 12 min read

How to Structure Laravel 13 Projects

16 lessons
1 h 32 min read

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.