Last active
April 26, 2024 02:05
-
-
Save CamKem/d1d3824139e69a0f721f88de395111b4 to your computer and use it in GitHub Desktop.
Laravel Polymorphic Follows System.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
use Illuminate\Database\Migrations\Migration; | |
use Illuminate\Database\Schema\Blueprint; | |
use Illuminate\Support\Facades\Schema; | |
return new class extends Migration | |
{ | |
public function up(): void | |
{ | |
Schema::create('follows', function (Blueprint $table) { | |
$table->id(); | |
$table->foreignId('user_id')->constrained()->onDelete('cascade'); | |
$table->morphs('followable'); | |
$table->unique(['user_id', 'followable_id', 'followable_type']); | |
$table->timestamps(); | |
}); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
// For code organisation, goes on the user model. | |
namespace App\Concerns; | |
use App\Models\Follow; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Relations\HasMany; | |
trait HandleFollows | |
{ | |
public function followers(): HasMany | |
{ | |
return $this->hasMany(Follow::class, 'followable_id', 'id') | |
->where('follows.followable_type', $this->getMorphClass()); | |
} | |
public function following(): HasMany | |
{ | |
return $this->hasMany(Follow::class, 'user_id', 'id'); | |
} | |
public function isFollowing(Model $model): bool | |
{ | |
if ($this->id === $model->id) { | |
return false; | |
} | |
return $this->following() | |
->where('follows.followable_type', $model->getMorphClass()) | |
->where('follows.followable_id', $model->id) | |
->exists(); | |
} | |
public function isFollowedBy(Model $model): bool | |
{ | |
return $this->followers()->where('user_id', $model->id)->exists(); | |
} | |
public function follow(Model $model): ?Model | |
{ | |
if (! $this->isFollowing($model)) { | |
return Follow::create([ | |
'user_id' => $this->id, | |
'followable_id' => $model->id, | |
'followable_type' => $model->getMorphClass(), | |
]); | |
} | |
return null; | |
} | |
public function unFollow(Model $model): int | |
{ | |
return $this->following() | |
->where('followable_id', $model->id) | |
->where('followable_type', $model->getMorphClass()) | |
->delete(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
// Goes on the models we want the user to allow to follow (Posts, Tags, etc...) | |
namespace App\Traits; | |
use App\Models\Follow; | |
use App\Models\User; | |
use Illuminate\Database\Eloquent\Relations\MorphMany; | |
trait HasFollowers | |
{ | |
public function followers(): MorphMany | |
{ | |
return $this->morphMany(Follow::class, 'followable'); | |
} | |
public function isFollowedBy(User $user): bool | |
{ | |
return $this->followers()->where('user_id', $user->id)->exists(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment