{"id":23456864,"url":"https://github.com/iksaku/laravel-mass-update","last_synced_at":"2025-05-15T20:07:13.680Z","repository":{"id":39059462,"uuid":"376352958","full_name":"iksaku/laravel-mass-update","owner":"iksaku","description":"Update multiple Laravel Model records, each with its own set of values, sending a single query to your database!","archived":false,"fork":false,"pushed_at":"2025-03-01T17:51:19.000Z","size":115,"stargazers_count":127,"open_issues_count":3,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-19T13:36:18.632Z","etag":null,"topics":["eloquent","laravel","php","sql"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iksaku.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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}},"created_at":"2021-06-12T17:53:57.000Z","updated_at":"2025-04-17T08:15:14.000Z","dependencies_parsed_at":"2024-03-23T21:33:30.546Z","dependency_job_id":"9bee4497-73f6-491b-8662-20c0e9faca50","html_url":"https://github.com/iksaku/laravel-mass-update","commit_stats":{"total_commits":46,"total_committers":4,"mean_commits":11.5,"dds":"0.17391304347826086","last_synced_commit":"b67922a1975a41742416902fa8ecd146059166fa"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":"spatie/package-skeleton-laravel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iksaku%2Flaravel-mass-update","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iksaku%2Flaravel-mass-update/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iksaku%2Flaravel-mass-update/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iksaku%2Flaravel-mass-update/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iksaku","download_url":"https://codeload.github.com/iksaku/laravel-mass-update/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414499,"owners_count":22067272,"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":["eloquent","laravel","php","sql"],"created_at":"2024-12-24T04:37:13.028Z","updated_at":"2025-05-15T20:07:08.635Z","avatar_url":"https://github.com/iksaku.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Mass Update\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/iksaku/laravel-mass-update.svg?style=flat-square)](https://packagist.org/packages/iksaku/laravel-mass-update)\n[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/iksaku/laravel-mass-update/run-tests.yml?branch=main\u0026label=tests)](https://github.com/iksaku/laravel-mass-update/actions/workflows/run-tests.yml?query=branch%3Amain)\n[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/iksaku/laravel-mass-update/php-cs-fixer.yml?branch=main\u0026label=code%20style)](https://github.com/iksaku/laravel-mass-update/actions/workflows/php-cs-fixer.yml?query=branch%3Amain)\n[![Total Downloads](https://img.shields.io/packagist/dt/iksaku/laravel-mass-update.svg?style=flat-square)](https://packagist.org/packages/iksaku/laravel-mass-update)\n\nUpdate multiple Laravel Model records, each with its own set of values, sending a single\nquery to your database!\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require iksaku/laravel-mass-update\n```\n\n## Usage\n\nIn your model class, add the `Iksaku\\Laravel\\MassUpdate\\MassUpdatable` trait:\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Iksaku\\Laravel\\MassUpdate\\MassUpdatable;\n\nclass User extends Model\n{\n    use MassUpdatable;\n    \n    // ...\n}\n```\n\nAnd that's all! Your model is now ready to update multiple records with varying values in a single query!\n\nLet's take a look at some possible use cases for this new query:\n\n### Simple use case: Update the values of multiple records\n\nImagine that you have the following `users` table:\n\n| id | name           | username |\n| -- | -------------- | -------- |\n| 1  | Jorge Gonzales | iksaku   |\n| 2  | Gladys Martines| gm_mtz   |\n\nBut, we want to update both records since those users have told us that their legal last name was misspelled:\n  * `González` is written with an accent on the letter `a`, and only uses `z`, never an `s`.\n  * `Martínez` is written with an accent on the letter `i`, and last letter should be a `z`, not an `s`\n\nWell, we can mass update those specific records:\n\n```php\nUser::massUpdate(\n    values: [\n        ['id' =\u003e 1, 'name' =\u003e 'Jorge González'],\n        ['id' =\u003e 2, 'name' =\u003e 'Gladys Martínez'],\n    ]\n);\n```\n\nNow, both records will be updated with their corresponding values in a single query, resulting in:\n\n| id | name            | username |\n| -- | --------------- | -------- |\n| 1  | Jorge González  | iksaku   |\n| 2  | Gladys Martínez | gm_mtz   |\n\nBy default, the `massUpdate` query will grab your model's primary key name and apply it as part of\nthe query to not affect other records.\n\nIf you want to use another column as an index to separate value types, you could pass it as a second\nargument to the function call:\n\n```php\nUser::massUpdate(\n    values: [\n        ['username' =\u003e 'iksaku', 'name' =\u003e 'Jorge González'],\n        ['username' =\u003e 'gm_mtz', 'name' =\u003e 'Gladys Martínez'],\n    ],\n    uniqueBy: 'username'\n);\n```\n\n### Simple use case #2: Updating multiple Eloquent Models\n\nIf you need to update the values in some Model classes and want to automatically mass update those changes,\nthen this is for you!\n\nThe existing `masUpdate` query is capable of identifying the _dirty_ attributes of `Eloquent` model classes\nand compile them properly. You don't need to manually convert the models into an array, you just pass the\nlist of models you want to update, and it takes care of the rest.\n\n\u003e Tip: If you pass a full list of `Eloquent` models, only those with _dirty_ values will be updated,\n\u003e so you don't actually need to filter the unchanged ones manually.\n\nLet's recreate the previous example, but using `Eloquent` models...\n\n```php\n// Say we already pulled our user models previously... Something like this:\n$jorge = User::where('name', 'Jorge Gonzales')-\u003efirst();\n$gladys = User::where('name', 'Gladys Martines')-\u003efirst();\n\n// And let's say we already made changes to those models... Like this:\n$jorge-\u003ename = 'Jorge González';\n$gladys-\u003ename = 'Gladys Martínez';\n\n// And now, let's update both models in a single query:\nUser::massUpdate(\n    values: [$jorge, $gladys]\n);\n```\n\nPretty cool, right?\n\n\u003e Note: It is only possible to mass update instances of the same `Eloquent` model,\n\u003e it is not possible to mix the _Query Builder_ with different `Eloquent` model classes.\n\n### Complicated use case: Using multiple indexes to differentiate records\n\nLet's say that we just created `expenses` table to track how much we spend across time, and\nwe manually filled the following values:\n\n| id | year | quarter | total_expenses |\n| -- | ---- | ------- | -------------- |\n| .. | ..   | ..      | ..             |\n| .. | 2019 | Q3      | 216.70         |\n| .. | 2019 | Q4      | 216.70         |\n| .. | 2020 | Q1      | `416.70`       |\n| .. | 2020 | Q2      | 211.12         |\n| .. | 2020 | Q3      | 113.17         |\n| .. | 2020 | Q4      | 422.89         |\n| .. | 2021 | Q1      | `431.35`       |\n\n\u003e Above information is not real, I don't track my expenses quarterly.\n\nOops... We made a little mistake... Expenses from Q1 of 2020 and 2021 are switched, and in order to fix it\nwe could only pass the `quarter` column as an index, but if we only pass down the `quarter` column as an index,\nwe'll modify **ALL** `Q1` records. So, for this, we should also pass down the `year` column as an index:\n\n```php\nExpense::massUpdate(\n    values: [\n        ['year' =\u003e 2020, 'quarter' =\u003e 'Q1', 'total_expenses' =\u003e 431.35],\n        ['year' =\u003e 2021, 'quarter' =\u003e 'Q1', 'total_expenses' =\u003e 416.70],\n    ],\n    uniqueBy: ['year', 'quarter']\n);\n```\n\n\u003e Tip: If you ever need to specify more than one or two indexes,\n\u003e just include all of them in the `values` and `uniqueBy` parameters.\n\nThe result in the table will be properly updated:\n\n| id | year | quarter | total_expenses |\n| -- | ---- | ------- | -------------- |\n| .. | ..   | ..      | ..             |\n| .. | 2020 | Q1      | `431.35`       |\n| .. | ..   | ..      | ..             |\n| .. | 2021 | Q1      | `416.70`       |\n\n\u003e **NOTE**: It is important that you always include the `uniqueBy` columns in your\n\u003e `values` array, exceptions will be thrown otherwise.\n\n\u003e **NOTE #2**: It is not possible to update the values of the `uniqueBy` columns.\n\u003e Every column specified in this parameter will be filtered from the ones that\n\u003e are going to be updated.\n\u003e\n\u003e This prevents unexpected side effects from happening while updating `values`\n\u003e in `array` shape and passed as `Eloquent` models.\n\n### Advanced use case: Chaining with other query statements\n\nLet's try to keep things simple and imagine a system that tracks _To-Do_ items for multiple users:\n\n| id | user_id | content                | order |\n| -- | ------- | ---------------------- | ----- |\n|  1 | 1       | Pick up my daughter    | 2     |\n|  2 | 1       | Buy a new ThinkPad     | 1     |\n|  3 | 1       | Drink water            | 3     |\n\nLike every _To-Do_ system, we let our users `order` their _To-Do_ items to see the most important ones at\nthe top of the list, and to do this, we may be using a [simple sorting package](https://github.com/asantibanez/laravel-blade-sortable)\nthat allows the user to drag items up and down the list.\n\nOnce the user moves one item in the list, in the backend we may receive an array with a specific key-value shape:\n`['position' =\u003e 'id']`. With this, we're going to update the records' `position` based on the given `id`.\n\nWe can simply call our `massUpdate` query function and everything will be done... Well, sort of...\n\nIn this specific scenario, we're dealing with **multiple lists for multiple users**, that means that we may not\nbe always able to control which `id` columns are sent to the server, maybe some malicious actor wants to hijack\nour _To-Do_ list and lower the priority for buying ThinkPads. This is a pretty serious security concern.\n\nThere are many ways to solve this kind of issues, and a simple one is to _chain query statements_ to our\n`massUpdate` function.\n\nIn this case, we're going to add a `where()` statement to only update those items that belong to the currently\nlogged in user. And it's as simple as in any other Laravel query builder:\n\n```php\nTodoItem::query()\n    -\u003ewhere('user_id', auth()-\u003eid())\n    -\u003emassUpdate(\n        values: collect($request-\u003einput('item_order'))\n            -\u003emapWithKeys(\n                fn ($id, int $position) =\u003e ['id' =\u003e $id, 'order' =\u003e $position]\n            )\n    );\n```\n\n\u003e Tip: Did you know you can pass Collections, LazyCollections, Eloquent Collections and basically\n\u003e any `Arrayable` instance as `values` to the `massUpdate` query function?\n\nThis can be used as an extra layer to ensure data integrity when dealing with User-provided input\nthat affects multiple records in the database.\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.\n\n## Security Vulnerabilities\n\nIf you discover any security related issues, please email yo@jorgeglz.io instead of using the issue tracker.\n\n## Credits\n\n- [Jorge González](https://github.com/iksaku)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiksaku%2Flaravel-mass-update","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiksaku%2Flaravel-mass-update","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiksaku%2Flaravel-mass-update/lists"}