My '@store' request feels ugly saving currency in decimal format.

Posted 2 years ago by SteamDiesel

Hey team, my store method is chock full of IF-checks to wash the request before I save it, I have a flexible form which is intended to be very forgiving for users who store incomplete data. For instance, some of the fields would only be completed 10% of the time, but when they are needed, it's critical to include them, and the absence of data means something to the users, too. The data is vehicle sales contract fields, so lots of different fields in a general repeatable format.

To make matters more exciting, I'm working with currency and using decimals for the data fields. So all currency fields in my migrations look like this:

$table->decimal('vehicle_price',10,2)->nullable;

I had issues getting my form to submit when the store method looked like this:

    public function store(Request $request)
    {
        $user = Auth::user();

        $deal = new VehicleDeal;

        $deal->make = request('make');
    $deal->vehicle_price = request('vehicle_price');
        $deal->odometer = request('odometer',0);
        $deal->build_date = request('build_date');
        $deal->user_id = $user->id;
        $deal->team_id = $user->currentTeam()->id;

        $deal->save();
    return back();
    }

the above code was giving me errors when I left fields blank:

SQLSTATE[HY000]: General error: 1366 Incorrect decimal value: '' for column 'vehicle_price' at row 1 and SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect date value: '' for column 'build_date' at row 1

I decided to just switch the odometer to a string, as some users may input the "...km" at the end, and I'd like to forgive them for it.

Anyway, to solve this problem I just started including if statements for each currency and date field, like this:

    public function store(Request $request)
    {
        $user = Auth::user();

        $deal = new VehicleDeal;

        $deal->make = request('make');
        if(request('vehicle_price')){
            $deal->vehicle_price = request('vehicle_price');
        }

        $deal->odometer = request('odometer',0);

        if(request('build_date')){
            $deal->build_date = request('build_date'); 
        }
        

        $deal->user_id = $user->id;
        $deal->team_id = $user->currentTeam()->id;

        $deal->save();
        return back();
}

This is the abridged version of my code, the true version has 13 decimal fields like vehicle_price and 2 date fields.

That's a lot of if-checking. I wondered if there was a more efficient way to grab this data and put it into the database. I decided that decimal was a simpler solution to storing currency, due to currency being a decimal, and then it shouldn't require division and multiplication if it were stored as integers. However, I'm open to reviewing this decision.

Also, I'm using the laravelcollective/html blade form layouts, if that makes any difference.

Please sign in or create an account to participate in this conversation.