Installation:
composer require miladimos/laravel-social
php artisan social:install
php artisan migrate
Add Miladimos\Social\Providers\SocialServiceProvider::class to config/app.php under providers.
Enable Follow/Unfollow:
Followable trait to your User model:
use Miladimos\Social\Traits\Follows\Followable;
php artisan vendor:publish --provider="Miladimos\Social\Providers\SocialServiceProvider"
First Use Case:
use App\Models\User;
$user = User::find(1);
$targetUser = User::find(2);
// Follow
$user->follow($targetUser);
// Unfollow
$user->unfollow($targetUser);
// Toggle (follow/unfollow)
$user->toggleFollow($targetUser);
config/socials.php (for customizing follow/unfollow behavior).Followable trait in Traits/Follows/Followable.php (core logic).database/migrations/[timestamp]_create_follows_table.php (schema for relationships).Basic Follow/Unfollow:
// Follow a user
$user->follow($targetUser);
// Check if followed
$user->isFollowing($targetUser); // Returns boolean
// Get followers/following
$user->followers(); // Collection of followers
$user->following(); // Collection of followed users
Batch Operations:
// Follow multiple users
$user->follow([$user1, $user2, $user3]);
// Unfollow multiple users
$user->unfollow([$user1, $user2]);
Event Listeners:
The package fires events (e.g., Followed, Unfollowed). Listen via:
use Miladimos\Social\Events\Followed;
event(new Followed($user, $targetUser));
Or register in EventServiceProvider:
protected $listen = [
Followed::class => [
'App\Listeners\LogFollowActivity',
],
];
API Integration: Useful for RESTful endpoints:
// Follow endpoint
public function follow(User $user, User $targetUser) {
$user->follow($targetUser);
return response()->json(['message' => 'Followed successfully']);
}
Route::middleware(['auth'])->group(function () {
Route::post('/follow/{user}', [FollowController::class, 'follow']);
});
$user->follow($targetUser);
Notification::send($targetUser, new UserFollowedNotification($user));
$user = User::with(['followers', 'following'])->find(1);
Missing Trait:
Forgetting to add Followable to the User model will cause MethodNotFoundException.
Fix: Ensure the trait is included in the model.
Circular Follows: The package does not prevent circular follows (A follows B, B follows A). Handle this in business logic if needed.
Database Constraints:
The follows table uses user_id and followed_user_id with unique constraint. Attempting to follow the same user twice will fail silently (no error, but no duplicate entry).
Debug: Check for silent failures by logging:
try {
$user->follow($targetUser);
} catch (\Exception $e) {
Log::error("Follow failed: " . $e->getMessage());
}
Model Caching:
If using model caching (e.g., remember()), ensure relationships are refreshed after follow/unfollow:
$user->follow($targetUser);
$user->refresh(); // Force reload relationships
DB::enableQueryLog();
$user->follow($targetUser);
dd(DB::getQueryLog());
php artisan tinker
>>> event(new \Miladimos\Social\Events\Followed($user, $targetUser));
Custom Follow Logic:
Override the follow method in your User model:
public function follow(User $user, $silent = false) {
// Custom logic (e.g., validate before following)
if ($user->isBlocked()) {
throw new \Exception("Cannot follow blocked user");
}
$this->followableFollow($user, $silent);
}
Additional Relationships: Extend the package to support "mutual follows" or "blocking":
// Add to Followable trait or create a new trait
public function isMutualFollow(User $user) {
return $this->following()->contains($user) && $user->following()->contains($this);
}
Custom Events: Extend the default events or create new ones:
class CustomFollowEvent extends Event {
public $user;
public $targetUser;
public $metadata;
public function __construct(User $user, User $targetUser, array $metadata) {
$this->user = $user;
$this->targetUser = $targetUser;
$this->metadata = $metadata;
}
}
API Resources: Create custom API resources for followers/following:
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'is_following' => auth()->user()->isFollowing($this),
];
}
auth guard. Override in config/socials.php:
'guard' => 'admin', // Custom guard name
User model uses soft deletes, ensure the follows table handles them:
// In Followable trait, modify queries to include `withTrashed()` if needed.
How can I help you explore Laravel packages today?