Bulk actions
A bulk action is typically a piece of code that you will run for many models. For example, to update all names in one go.
In our platform, Bulk Actions are utilized heavily, and is a prefered way of working for many of our employees.
Due to it being identical 99,9% of the time, we've extracted bulk actions to its own service, so that there's one API and the logic is the same either way.
It is important to note that bulk actions relies completely on the service string.
Building bulk actions
Bulk actions always contain a payload which contains the data used in to perform a bulk action. The POST /api/admin/bulk-action sets everything up.
A bulk action must extend the App\Services\BulkAction\Actions\Root class. This base class handles figuring out which actions need to be sent to the queue and contains the method for collecting models.
Bulk actions are basically jobs, but instead of encapsulating the action in the handle method, you instead add it to a method called start.
A action that is sent to the queue would need to implement the Illuminate\Contracts\Queue\ShouldQueue contract and would look something like this.
use App\Services\BulkAction\Actions\Root;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class MyAwesomeAction extends Root implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function start()
{
$this->getModels()->each->doSomething();
}
}
A action that is run synchronously would look something like this.
use App\Services\BulkAction\Actions\Root;
class MyAwesomeAction extends Root
{
public function start()
{
$this->getModels()->each->doSomething();
}
}
Please due note that even though you prefer to send this bulk action to the queue, it might not actually be sent to the queue. Only bulk actions that contain 10 models are more are sent to the queue.
You can change this behavior by overriding the getType method on your bulk action.
public function getType()
{
return 'async'; // should be 'async' or 'sync'
}
Running on models
As mentioned bulk actions rely on the service string and is able to collect models based on this. To get the models, you can use the getModels helper which gives you a Eloquent-collection of the models.
You can also get the query itself if you need, by using the getFilteredQuery method. This returns a Eloquent builder, but is filtered down to the models you need. You could use it to, for example, delete all filtered models.
Registering bulk actions
To register bulk actions, you would do it from the ServiceProvider in the service you are currently working in. In the service providers register method add:
bulkAction()->register(MyAwesomeBulkAction::class);
You can even register a closure
bulkAction()->register('update-name', function($action) {
$action->getModels()->each(function($model) {
$model->update(['first_name' => $this->payload->name]);
});
});
This is chainable so you can register many bulk actions in one go.
bulkAction()
->register(MyAwesomeBulkAction::class)
->register(MyOtherAwesomeBulkAction::class)
->register(MyNotSoAwesomeBulkAction::class);
Using bulk actions
Bulk actions can be used in two ways. Either by invoking them through the api POST /api/admin/bulk-action or by instantiating them through the manager, accessible via the bulkAction() helper:
$action = bulkAction()->create(
MyAction::class, // class name
'project:1:everyone', // service string
['foo' => 'bar'], // payload
[], // filters
[], // specific ids
auth()->user()->id, // the id of the user performing the action
null, // an option row id from the `bulk_actions` table
);
This would give you an instance of the MyAction class which you can use for several things.
Validation
Each bulk action has the ability to validate itself. You would invoke this by calling the validate method.
You define the rules in the rules method and the messages in the messages method.
A validation error will throw a Illuminate\Validation\ValidationException.
Run the action
You can run the action by calling the run method. This performs the necessary checks to see where this action goes (sync/async).
Bulk Actions in the client
Currently bulk actions have to be implemented manually, but there are some helpers to fire them.