In this lesson, we will repeat most of the steps we made for our Categories CRUD. But this time, we will create Transactions CRUD. Here's a quick overview:
- Creating Models, Migrations
- Creating Request classes
- Creating TransactionController with CRUD methods
- Creating TransactionResource
- Adding API routes
So, let's dive into it.
Creating Models, Migrations
Let's start by creating our Model with migrations:
php artisan make:model Transaction -m
Then, let's update the migration file:
Migration
Schema::create('transactions', function (Blueprint $table) { $table->id(); $table->foreignId('category_id')->constrained(); $table->foreignId('user_id')->nullable()->constrained(); $table->date('transaction_date'); $table->integer('amount'); $table->string('description'); $table->timestamps();});
Our Model, which will have an amount attribute that will be cast to cents:
app/Models/Transaction.php
use Illuminate\Database\Eloquent\Builder;use Illuminate\Database\Eloquent\Casts\Attribute;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsTo; class Transaction extends Model{ protected $fillable = [ 'category_id', 'user_id', 'transaction_date', 'amount', 'description', ]; protected function casts() { return [ 'transaction_date' => 'date', ]; } protected function amount(): Attribute { return Attribute::make( get: fn($value) => $value / 100, set: fn($value) => $value * 100, ); } public function user(): BelongsTo { return $this->belongsTo(User::class); } public function category(): BelongsTo { return $this->belongsTo(Category::class); }}
Because our Transactions are tied with Categories, we need to add a relationship to the categories Model:
app/Models/Category.php
use Illuminate\Database\Eloquent\Relations\HasMany; // ... public function transactions(): HasMany{ return $this->hasMany(Transaction::class);}
Creating Request Classes
Let's create our Request classes:
php artisan make:request StoreTransactionRequestphp artisan make:request UpdateTransactionRequest
app/Http/Requests/StoreTransactionRequest.php
public function rules(): array{ return [ 'category_id' => ['required', 'integer'], 'user_id' => ['nullable', 'integer'], 'transaction_date' => ['required', 'date'], 'amount' => ['required', 'numeric'], 'description' => ['required'], ];} public function authorize(): bool{ return true;}
And our Update request (which is the same as the Store request):
app/Http/Requests/UpdateTransactionRequest.php
public function rules(): array{ return [ 'category_id' => ['required', 'integer'], 'user_id' => ['nullable', 'integer'], 'transaction_date' => ['required', 'date'], 'amount' => ['required', 'numeric'], 'description' => ['required'], ];} public function authorize(): bool{ return true;}
Creating TransactionResource
Next, let's create our TransactionResource:
php artisan make:resource TransactionResource
This will help us to format our response data:
app/Http/Resources/TransactionResource.php
/** @mixin Transaction */class TransactionResource extends JsonResource{ public function toArray(Request $request): array { return [ 'id' => $this->id, 'category_id' => $this->category_id, 'category_name' => $this->category->name, 'amount' => number_format($this->amount, 2), 'transaction_date' => $this->transaction_date->format('m/d/Y'), 'description' => $this->description, 'created_at' => $this->created_at, ]; }}
Creating TransactionController with CRUD Methods
And finally, we can prepare our Controller with simple CRUD actions:
php artisan make:controller Api/TransactionController --resource --api --model=Transaction
And just like with our Categories, we will fill it with basic actions:
Note: There is nothing new here; we repeat the same steps we did with Categories.
app/Http/Controllers/Api/TransactionController.php
use App\Http\Controllers\Controller;use App\Http\Requests\StoreTransactionRequest;use App\Http\Resources\TransactionResource;use App\Models\Transaction;use Illuminate\Http\Request; class TransactionController extends Controller{ /** * Display a listing of the resource. */ public function index() { return TransactionResource::collection(Transaction::all()); } /** * Store a newly created resource in storage. */ public function store(StoreTransactionRequest $request) { return new TransactionResource(Transaction::create($request->validated())); } /** * Display the specified resource. */ public function show(Transaction $transaction) { return new TransactionResource($transaction); } /** * Update the specified resource in storage. */ public function update(UpdateTransactionRequest $request, Transaction $transaction) { $transaction->update($request->validated()); return new TransactionResource($transaction); } /** * Remove the specified resource from storage. */ public function destroy(Transaction $transaction) { $transaction->delete(); return response()->noContent(); }}
Adding API Routes
The last thing to do is register our routes:
routes/api.php
use App\Http\Controllers\Api\TransactionController; // ... Route::apiResource('transactions', TransactionController::class);
That's it! We have our Transactions CRUD ready.
In the next lesson, we will take our existing API and add Sanctum API Authentication around it. This will allow us to secure our API endpoints and allow only authenticated users to access them.
Check out the GitHub Commit
The "UpdateTransactionRequest" is missing inside the TransactionController code-block.
Updated! Thank you!