Home > OS >  Best Practice Interpreting SQL Data with Switch/Case To Avoid Unnecessary Eloquent Calls
Best Practice Interpreting SQL Data with Switch/Case To Avoid Unnecessary Eloquent Calls

Time:12-21

I'm still new to Inertia/VUE3 & Laravel. I'm more familiar with PHP but I want to use best practices for what I'm doing here. I'm sure it's relatively simple so I appreciate all your help. I just wasn't sure what to search in looking for a solution.

I'm essentially creating a facade for a somewhat spaghetti ASP.NET app my company uses. There are several data points that are integers that point to another table for translation in their app. I do not want to recreate their database structure completely with Eloquent so I'd like to create a few functions on the model (I think that's what I need to do) to interpret some of this data being returned from my initial query for display. I'm wondering whether I should do this in my model, controller, or vue file.

In this example, the "StatusID" is an integer which is then translated to something like "Posted", "Cancelled", etc. I don't want to make a call to the DB just to get these translations.

Controller

<?php

namespace App\Http\Controllers;

use Inertia\Inertia;
use Illuminate\Http\Request;
use App\Models\eRequester\Requisition;
use App\Models\eRequester\ProjectManager;

class RequisitionController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return Inertia::render('Requisition/Index',[
                'requisitions' => Requisition::with(
                    'lines:RequisitionLineID,ItemID,Description,ProjectNumber,RequisitionID',
                    'owner:UserID,UserName,FirstName,LastName')
                    ->latest()
                    ->where('StatusID','!=','2')
                    ->limit(15)
                    ->select('RequisitionID','Title','UserID')
                    ->get(),
                'projectmanagers' => ProjectManager::where('AttributeID','siica3')
                    ->orWhere('AttributeID','ckwca7')
                    ->orWhere('AttributeID','orica3')
                    ->get(),
            ]);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\eRequester\Requisition  $requisition
     * @return \Illuminate\Http\Response
     */
    public function show(Requisition $requisition)
    {
        //
    }

}

Model

<?php

namespace App\Models\eRequester;

use App\Models\eRequester\ERequesterUser;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Requisition extends Model
{
    protected $connection = '{redacted}';
    protected $table = 'Requisition';
    protected $primaryKey = 'RequisitionID';
    const CREATED_AT = 'DateRequested';
    const UPDATED_AT = 'DateSubmitted';

    public function lines(){
        return $this->hasMany(RequisitionLine::class, 'RequisitionID');
    }

    public function owner(){
        return $this->belongsTo(ERequesterUser::class, 'UserID');
    }

}

Vue

<script setup>
import { Link, button } from '@inertiajs/inertia-vue3';

defineProps(['req','pm']);
</script>

<template>
    <div >
        <div >
            <span >
                
            <a target="_BLANK" :href="'https://erequester.spitzerind.net:8080/req/review.aspx?reqid='   req.RequisitionID">
                <button >
                    {{ req.RequisitionID }}
                </button></a>
                    {{ req.Title }}
            </span>
            <span >
                {{ req.owner.FirstName}} {{req.owner.LastName}}
            </span>
            
        </div>
        <div v-for="line in req.lines" 
            :key="line.RequisitionLineID"
            :line="line">
            {{ line.RequisitionLineID }}: {{ line.ItemID }} | {{ line.Description }} | {{ line.ProjectNumber }}
            </div>
    </div>

I've tried to translate at the controller level in my inertia render and also tried to translate via the model, but I know there's probably some really simple solution which I'm missing.

On my model I thought maybe I could use a public function, but I wasn't sure how to supply the data from the controller. I also wasn't sure whether this was the smartest way to do this. I'd like for it to use PHP as opposed to JS since it won't be changing and with a basic understanding of progressive enhancement.

public function status($statusID){
        // Translation switch/case
    }

I would like to be able to use PHP to translate some simple integer data into human-readable format.

CodePudding user response:

I would probably use some sort of enum

https://www.php.net/manual/en/language.enumerations.backed.php
https://github.com/spatie/laravel-enum

enum StatusEnum: int
{
    case Posted = 1;
    case Cancelled = 2;
    case SomethingElse = 3;
}
class Requisition extends Model
{
    protected $casts = [
        'statusID' => StatusEnum::class
    ];

    // $requisition->status->value === 1
    public function getStatusAttribute()
    {
        return $this->getAttribute('statusID');
    }

    // magic method to make `Requisition::whereStatus(StatusEnum::Posted)` work
    public function scopeWhereStatus($query, $value)
    {
        $query->where('statusId', $value);
    }

    // Requisition::with('...')->wherePosted()->latest()
    public function scopeWherePosted($query)
    {
        $query->where('statusId', StatusEnum::Posted);
    }
}
Requisition::where('statusID', StatusEnum::Posted)

https://enversanli.medium.com/how-to-use-enums-with-laravel-9-d18f1ee35b56

  • Related