|
| 1 | +# Creating Your First Operation |
| 2 | + |
| 3 | +After installing the package you'll no doubt want to get started by creating an operation. |
| 4 | + |
| 5 | +In this guide, we'll imagine that we're building an app where every user has a `rank` column that just holds a string. When the user first signs up they have a "New" rank, and after one week they get upgraded to be a "Beginner". Our operation will be scheduled to run one week after the user signs up and will update that `rank` column to the "Beginner" value. |
| 6 | + |
| 7 | +If you would like to follow along in your own project, you can create a fresh Laravel installation, set up the authentication scaffolding, and add a string `rank` column to your user model. Then follow the instructions in the [README](/README.md#installation) to install the package. |
| 8 | + |
| 9 | +To begin, you'll need an operation model and a database table for it. You can create these easily using the `make:operation` command with a flag to also create the migration: |
| 10 | + |
| 11 | +```bash |
| 12 | +php artisan make:operation RankUpUserOperation -m |
| 13 | +``` |
| 14 | + |
| 15 | +This will give you two new files: `app\Operations\RankUpUserOperation.php` and a `create_rank_up_user_operations` migration. |
| 16 | + |
| 17 | +Because this operation is updating a column on a user model, we'll need to be able to store which user ID we need to update. Open up the migration file and add an additional `user_id` column: |
| 18 | + |
| 19 | +```php |
| 20 | +<?php |
| 21 | + |
| 22 | +// Use Statements |
| 23 | + |
| 24 | +class CreateRankUpUserOperations extends Migration |
| 25 | +{ |
| 26 | + public function up() { |
| 27 | + Schema::create('rank_up_user_operations', function (Blueprint $table) { |
| 28 | + $table->bigIncrements('id'); |
| 29 | + |
| 30 | + // Custom User ID Column |
| 31 | + $table->unsignedBigInteger('user_id'); |
| 32 | + |
| 33 | + // Timestamps |
| 34 | + }); |
| 35 | + } |
| 36 | + |
| 37 | + // ... |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +You can now run `php artisan migrate` to create the table. Once that is done we can move on to writing the code in the operation. |
| 42 | + |
| 43 | +> **Remember!** Every operation needs to have a `run` method implemented. The abstract Operation object that your Operation extends doesn't have an abstract `run` method to allow for dependency injection, so it's up to you to remember. But don't worry too much; if you forget to add it you will be reminded by an exception as soon as you try to use it. |
| 44 | +
|
| 45 | +```php |
| 46 | +<?php |
| 47 | + |
| 48 | +namespace App\Operations; |
| 49 | + |
| 50 | +use App\User; |
| 51 | +use DealerInspire\Operations\Operation; |
| 52 | + |
| 53 | +class RankUpUserOperation extends Operation |
| 54 | +{ |
| 55 | + public function run() |
| 56 | + { |
| 57 | + User::where('id', $this->user_id)->update(['rank' => 'Beginner']); |
| 58 | + } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +Simple as that! Now any time our operation is run, the user associated to this operation will get a rank of `Beginner`. |
| 63 | + |
| 64 | +We've created our new `RankUpUserOperation` but before we can start using it we need to make sure that we register it in our `operations.php` config file. If you don't have that file yet, make sure to run the `vendor:publish` artisan command to get it. Once you have that file you just need to reference your new operation class in the `operations` array: |
| 65 | + |
| 66 | +```php |
| 67 | +'operations' => [ |
| 68 | + \App\Operations\RankUpUserOperation::class, |
| 69 | +], |
| 70 | +``` |
| 71 | + |
| 72 | +Now that we have an operation and have it registered so that the package knows about it, we need a way to save new operations to our database. In this case, we've decided that this operation should run for each user one week after they sign up. |
| 73 | + |
| 74 | +To accomplish this we could use an observer and listen for any time a User is created, but for the purpose of keeping it simple we'll just create an operation at the same time we create the user. To do that you should open up `app\Http\Controllers\Auth\RegisterController.php` and change the `create` function to look like the following: |
| 75 | + |
| 76 | +```php |
| 77 | +protected function create(array $data) |
| 78 | +{ |
| 79 | + $user = User::create(/* ... */); |
| 80 | + |
| 81 | + RankUpUserOperation::schedule(Carbon::now()->addWeek(), [ |
| 82 | + 'user_id' => $user->id, |
| 83 | + ]); |
| 84 | + |
| 85 | + return $user; |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +The static `schedule` function is a helpful little way to more coherently create an operation. It simply takes the time when you want the operation to run and an optional array if you have additional attributes you need to set, like our `user_id`. If you don't have any custom attributes to set then you can just leave off the array entirely. If you're not a fan of these kinds of static methods, don't worry. You can still create an instance of your operation and save it however you'd like, just so long as you remember to set `should_run_at`. |
| 90 | + |
| 91 | +If you browse to your Laravel project now in your browser and register a new account, you should not only see a new record in the `users` table, but also a new record in the `rank_up_user_operations` table that has your new user's ID and a `should_run_at` timestamp set to one week in the future. |
| 92 | + |
| 93 | +You could wait a week to try and see if the operation works, but since I'm rather impatient I'm going to modify my database record to have a `should_run_at` timestamp of a few minutes in the future. You could also remove the `addWeek` call on the Carbon instance and create another new user if you don't want to tinker around in your database. |
| 94 | + |
| 95 | +In the next guide we'll be going over how you can actually get these operations to run when they're ready. For right now I'm going to use artisan tinker to do it, by calling the Operator's `queue` method through the facade. |
| 96 | + |
| 97 | +```bash |
| 98 | +php artisan tinker |
| 99 | +``` |
| 100 | + |
| 101 | +``` |
| 102 | +DealerInspire\Operations\Facades\Operator::queue() |
| 103 | +``` |
| 104 | + |
| 105 | +If your queue driver is set to `sync` then everything should finish, well, synchronously. If you have your driver set to anything else make sure to run `php artisan queue:work` or whatever else you need to do to handle the job that gets created by running the `queue` command. |
| 106 | + |
| 107 | +After the job has finished processing you should see that the Operation record in the database has timestamps set for `started_run_at` and `finished_run_at`, and the User record's `rank` has been updated to "Beginner". |
| 108 | + |
| 109 | +Next: [How to Queue Operations](/docs/queueing.md) |
0 commit comments