{"id":17922681,"url":"https://github.com/overtrue/laravel-vote","last_synced_at":"2025-05-16T13:05:58.901Z","repository":{"id":41551544,"uuid":"368528004","full_name":"overtrue/laravel-vote","owner":"overtrue","description":"⬆️ ⬇️ User vote system for Laravel Application.","archived":false,"fork":false,"pushed_at":"2025-02-25T13:38:28.000Z","size":46,"stargazers_count":120,"open_issues_count":2,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-13T19:17:12.888Z","etag":null,"topics":["laravel-vote","user-vote","vote","voter-vote-status"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/overtrue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["overtrue"]}},"created_at":"2021-05-18T12:49:43.000Z","updated_at":"2025-04-22T17:40:55.000Z","dependencies_parsed_at":"2024-02-17T06:31:12.257Z","dependency_job_id":"801d0dd7-eb7f-4aef-a8ed-d7d523f29337","html_url":"https://github.com/overtrue/laravel-vote","commit_stats":{"total_commits":36,"total_committers":4,"mean_commits":9.0,"dds":0.08333333333333337,"last_synced_commit":"d3dc02d785d44bf6cbdfc2fc34c1346518e7fb51"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-vote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-vote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-vote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-vote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/overtrue","download_url":"https://codeload.github.com/overtrue/laravel-vote/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254535827,"owners_count":22087399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel-vote","user-vote","vote","voter-vote-status"],"created_at":"2024-10-28T20:40:26.404Z","updated_at":"2025-05-16T13:05:58.843Z","avatar_url":"https://github.com/overtrue.png","language":"PHP","funding_links":["https://github.com/sponsors/overtrue"],"categories":[],"sub_categories":[],"readme":"Laravel Vote\n---\n\n⬆️ ⬇️ User vote system for Laravel Application.\n\n[![CI](https://github.com/overtrue/laravel-vote/workflows/CI/badge.svg)](https://github.com/overtrue/laravel-vote/actions/workflows/ci.yml)\n\n[![Sponsor me](https://github.com/overtrue/overtrue/blob/master/sponsor-me-button-s.svg?raw=true)](https://github.com/sponsors/overtrue)\n\n\n## Installing\n\n```shell\ncomposer require overtrue/laravel-vote -vvv\n```\n\n### Configuration \u0026 Migrations\n\n\n```shell\nphp artisan vendor:publish \n```\n\nthen create tables: \n\n```bash\nphp artisan migrate\n```\n\n## Usage\n\n### Traits\n\n#### `Overtrue\\LaravelVote\\Traits\\Voter`\n\n```php\n\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Contracts\\Auth\\MustVerifyEmail;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Overtrue\\LaravelVote\\Traits\\Voter;\n\nclass User extends Authenticatable\n{\n    use Voter;\n    \n    \u003c...\u003e\n}\n```\n\n#### `Overtrue\\LaravelVote\\Traits\\Voteable`\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Overtrue\\LaravelVote\\Traits\\Votable;\n\nclass Idea extends Model\n{\n    use Votable;\n\n    \u003c...\u003e\n}\n```\n\n### API\n\n```php\n$user = User::find(1);\n$idea = Idea::find(2);\n\n$user-\u003evote($idea, 1); // upvote\n$user-\u003evote($idea, -1); // downvote\n$user-\u003eupvote($idea);\n$user-\u003edownvote($idea);\n\n// with custom number of votes\n$user-\u003eupvote($idea, 3);\n$user-\u003edownvote($idea, 3);\n\n// cancel vote\n$user-\u003ecancelVote($idea);\n\n// get my voted items\n$user-\u003egetVotedItems(Idea::class) // Illuminate\\Database\\Eloquent\\Builder\n\n// state\n$user-\u003ehasVoted($idea); \n$idea-\u003ehasBeenVotedBy($user); \n```\n\n#### Get model voters:\n\n```php\nforeach($idea-\u003evoters as $user) {\n    // echo $user-\u003ename;\n}\n```\n\n#### Get user voted items.\n\nUser can easy to get Votable models to do what you want.\n\n*note: this method will return a `Illuminate\\Database\\Eloquent\\Builder` *\n\n```php\n$votedItemsQuery = $user-\u003egetVotedItems();\n\n// filter votable_type\n$votedIdeasQuery = $user-\u003egetVotedItems(Idea::class);\n\n// fetch results\n$votedIdeas = $user-\u003egetVoteItems(Idea::class)-\u003eget();\n$votedIdeas = $user-\u003egetVoteItems(Idea::class)-\u003epaginate();\n$votedIdeas = $user-\u003egetVoteItems(Idea::class)-\u003ewhere('title', 'Laravel-Vote')-\u003eget();\n```\n\n### Aggregations\n\n### count relations\n```php\n// all\n$user-\u003evotes()-\u003ecount(); \n\n// filter votable_type\n$user-\u003evotes()-\u003eofType(Idea::class)-\u003ecount(); \n\n// voters count\n$idea-\u003evoters()-\u003ecount();\n```\n\nList with `*_count` attribute:\n\n```php\n// for Voter models:\n$users = User::withCount('votes')-\u003eget();\n// or\n$users = User::withCount('upvotes')-\u003eget();\n// or\n$users = User::withCount('downvotes')-\u003eget();\n// or\n$users = User::withCount(['votes', 'upvotes', 'downvotes'])-\u003eget();\n\nforeach($users as $user) {\n    echo $user-\u003evotes_count;\n    echo $user-\u003eupvotes_count;\n    echo $user-\u003edownvotes_count;\n}\n\n// for Votable models: \n$ideas = Idea::withCount('voters')-\u003eget();\n// or\n$ideas = Idea::withCount('upvoters')-\u003eget();\n$ideas = Idea::withCount('downvoters')-\u003eget();\n\n// or\n$ideas = Idea::withCount(['voters', 'upvoters', 'downvoters'])-\u003eget();\n\nforeach($ideas as $idea) {\n    echo $idea-\u003evoters_count;\n    echo $idea-\u003eupvoters_count;\n    echo $idea-\u003edownvoters_count;\n}\n```\n\n### Votable sum votes\n\n```php\n$user1-\u003eupvote($idea); // 1 (up)\n$user2-\u003eupvote($idea); // 2 (up)\n$user3-\u003eupvote($idea); // 3 (up)\n$user4-\u003edownvote($idea); // -1 (down)\n\n// sum(votes)\n$idea-\u003etotalVotes(); // 2(3 - 1)\n\n// sum(votes) where votes \u003e 0\n$idea-\u003etotalUpvotes(); // 3\n\n// abs(sum(votes)) where votes \u003c 0\n$idea-\u003etotalDownvotes(); // 1\n\n// appends aggregations attributes\n$idea-\u003eappendsVotesAttributes();\n$idea-\u003etoArray();\n// result\n[\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Add socialite login support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \n    // these aggregations attributes will be appends.\n    \"total_votes\" =\u003e 2\n    \"total_upvotes\" =\u003e 3\n    \"total_downvotes\" =\u003e 1\n  ],\n```\n\n### Attach voter vote status to votable collection\n\nYou can use `Voter::attachVoteStatus(Collection $votables)` to attach the voter vote status, it will set `has_voted`,`has_upvoted` and `has_downvoted` attributes to each model of `$votables`:\n\n#### For model\n```php\n$idea = Idea::find(1);\n\n$user-\u003eattachVoteStatus($idea);\n\n// result\n[\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Add socialite login support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_voted\" =\u003e true\n    \"has_upvoted\" =\u003e true\n    \"has_downvoted\" =\u003e false\n ],\n```\n\n#### For `Collection | Paginator | LengthAwarePaginator | array`:\n\n```php\n$ideas = Idea::oldest('id')-\u003eget();\n\n$user-\u003eattachVoteStatus($ideas);\n\n$ideas = $ideas-\u003etoArray();\n\n// result\n[\n  [\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Add socialite login support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_voted\" =\u003e true\n    \"has_upvoted\" =\u003e true\n    \"has_downvoted\" =\u003e false\n  ],\n  [\n    \"id\" =\u003e 2\n    \"title\" =\u003e \"Add php8 support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_voted\" =\u003e true\n    \"has_upvoted\" =\u003e false\n    \"has_downvoted\" =\u003e true\n  ],\n  [\n    \"id\" =\u003e 3\n    \"title\" =\u003e \"Add qrcode support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_voted\" =\u003e false\n    \"has_upvoted\" =\u003e false\n    \"has_downvoted\" =\u003e false\n  ],\n]\n```\n\n#### For pagination\n\n```php\n$ideas = Idea::paginate(20);\n\n$user-\u003eattachVoteStatus($ideas-\u003egetCollection());\n```\n\n### N+1 issue\n\nTo avoid the N+1 issue, you can use eager loading to reduce this operation to just 2 queries. When querying, you may specify which relationships should be eager loaded using the `with` method:\n\n```php\n// Voter\nuse Tests\\Idea;$users = User::with('votes')-\u003eget();\n\nforeach($users as $user) {\n    $user-\u003ehasVoted($idea);\n}\n\n// Votable\n$ideas = Idea::with('voters')-\u003eget();\n\nforeach($ideas as $idea) {\n    $idea-\u003ehasBeenVotedBy($user);\n}\n\n// Votable votes\n$ideas = Idea::withTotalVotes() // total_votes\n        -\u003ewithTotalUpvotes() // total_upvotes\n        -\u003ewithTotalDownvotes() // total_downvotes\n        -\u003eget();\n\n// same as\n// withVotesAttributes() = withTotalVotes() + withTotalUpvotes() + withTotalDownvotes() \n$ideas = Idea::withVotesAttributes()-\u003eget();\n\n// result\n[\n  [\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Add socialite login support.\"\n    \"created_at\" =\u003e \"2021-05-19T07:01:10.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-19T07:01:10.000000Z\"\n    \"total_votes\" =\u003e 2\n    \"total_upvotes\" =\u003e 3\n    \"total_downvotes\" =\u003e 1\n  ],\n  [\n    \"id\" =\u003e 2\n    \"title\" =\u003e \"Add PHP8 support.\"\n    \"created_at\" =\u003e \"2021-05-20T07:01:10.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T07:01:10.000000Z\"\n    \"total_votes\" =\u003e 1\n    \"total_upvotes\" =\u003e 2\n    \"total_downvotes\" =\u003e 1\n  ]\n]\n```\n\n### Events\n\n| **Event** | **Description** |\n| --- | --- |\n|  `Overtrue\\LaravelVote\\Events\\Voted` | Triggered when the relationship is created. |\n|  `Overtrue\\LaravelVote\\Events\\VoteCancelled` | Triggered when the relationship is deleted. |\n\n## Related packages\n\n- Follow: [overtrue/laravel-follow](https://github.com/overtrue/laravel-follow)\n- Like: [overtrue/laravel-like](https://github.com/overtrue/laravel-like)\n- Vote: [overtrue/laravel-vote](https://github.com/overtrue/laravel-Vote)\n- Subscribe: [overtrue/laravel-subscribe](https://github.com/overtrue/laravel-subscribe)\n- Bookmark: overtrue/laravel-bookmark (working in progress)\n\n## :heart: Sponsor me \n\n[![Sponsor me](https://github.com/overtrue/overtrue/blob/master/sponsor-me.svg?raw=true)](https://github.com/sponsors/overtrue)\n\n如果你喜欢我的项目并想支持它，[点击这里 :heart:](https://github.com/sponsors/overtrue)\n\n\n## Project supported by JetBrains\n\nMany thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.\n\n[![](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/overtrue)\n\n## Contributing\n\nYou can contribute in one of three ways:\n\n1. File bug reports using the [issue tracker](https://github.com/overtrue/laravel-Votes/issues).\n2. Answer questions or fix bugs on the [issue tracker](https://github.com/overtrue/laravel-Votes/issues).\n3. Contribute new features or update the wiki.\n\n_The code contribution process is not very formal. You just need to make sure that you follow the PSR-0, PSR-1, and PSR-2 coding guidelines. Any new code contributions must be accompanied by unit tests where applicable._\n\n## PHP 扩展包开发\n\n\u003e 想知道如何从零开始构建 PHP 扩展包？\n\u003e\n\u003e 请关注我的实战课程，我会在此课程中分享一些扩展开发经验 —— [《PHP 扩展包实战教程 - 从入门到发布》](https://learnku.com/courses/creating-package)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovertrue%2Flaravel-vote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fovertrue%2Flaravel-vote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovertrue%2Flaravel-vote/lists"}