Installation:
composer require rtconner/laravel-likeable
php artisan migrate
likes table with likeable_id, likeable_type, user_id, and created_at columns.Apply to a Model:
use Conner\Likeable\Likeable;
class Article extends Model
{
use Likeable;
}
First Use Case:
$article = Article::find(1);
$article->like(); // Likes for authenticated user
$article->likeCount; // Returns integer count
php artisan migrate to set up the database table.use Likeable; in any Eloquent model needing like functionality.like(), unlike(), liked()) in Tinker or a controller.Basic Like/Unlike:
// Authenticated user
$post->like(); // Adds like record
$post->unlike(); // Removes like record
// Anonymous or custom user
$post->like($userId); // Explicit user ID
$post->unlike($userId);
Counting and Checking:
$post->likeCount; // Integer count
$post->liked(); // Boolean: true if current user liked
$post->liked($userId); // Check for specific user
Query Scopes:
// Get posts liked by user
$userLikedPosts = Post::whereLikedBy(auth()->id())->get();
// Get posts with >10 likes
$popularPosts = Post::where('like_count', '>', 10)->get();
auth()->id() for seamless integration with Laravel’s auth system.$post->like($request->user_id);
likeCount in Redis for high-traffic models:
Cache::remember("post:{$post->id}:likes", now()->addHours(1), fn() => $post->likeCount);
Polymorphic Likes:
// Works out-of-the-box for any model using the trait
$comment->like(); // Uses same table as Article
Batch Operations:
// Unlike all posts by a user
Post::where('user_id', $userId)->get()->each->unlike($userId);
Customizing the Likeable Table:
Override getLikeableTable() in your model:
public function getLikeableTable()
{
return 'custom_likes';
}
Migration Errors:
likes table exists. Run php artisan migrate if skipped.User ID Handling:
0 as $userId increments/decrements the count without tracking a user. Use sparingly.unlike(0) removes all likes (resets count to 0). Confirm intent before use.Polymorphic Conflicts:
likeable_type (e.g., don’t use type as a model column).$post->getLikeableTable(); // Verify table name
$post->getLikeableKey(); // Verify key column (default: 'id')
Performance:
likes collection loads all like records. Use likeCount for counts or limit with:
$post->likes()->limit(5)->get();
Check Like Records:
$post->likes; // Inspect raw records
$post->likes()->where('user_id', $userId)->exists(); // Verify existence
Log Queries:
Enable Laravel’s query logging in config/database.php:
'log' => env('DB_LOG_QUERIES', false),
Then check storage/logs/laravel.log.
Override Methods: Extend the trait for custom logic:
class Article extends Model
{
use Likeable;
public function like($userId = null)
{
if ($this->isPremiumUser()) {
// Custom logic
}
parent::like($userId);
}
}
Custom Columns:
Override getLikeableKey() or getLikeableForeignKey():
public function getLikeableKey()
{
return 'slug'; // Use slug instead of ID
}
Event Hooks: Listen for like/unlike events:
Likeable::like(function ($model, $userId) {
event(new PostLiked($model, $userId));
});
Validation: Add middleware to validate user actions:
public function unlike($userId = null)
{
if ($this->isBanned()) {
abort(403);
}
parent::unlike($userId);
}
auth()->id() by default. For APIs, override or pass IDs explicitly.likes table also has a deleted_at column and update the trait’s queries accordingly.likes table includes created_at but not updated_at. Add if needed:
public function getLikeableCreatedAtColumn()
{
return 'created_at';
}
How can I help you explore Laravel packages today?