ale1981's avatar

Trim char data type

I am working with an old MS SQL database where nearly all string columns are of type char.

Is there a way I can trim the original values before Laravel captures them?

I have added the following to the Model but this seems to be causing issues with isDirty() flagging all the columns as dirty as they no longer have the whitespace at the end.

/**
 * Get a plain attribute (not a relationship).
 *
 * @param  string  $key
 * @return mixed
 */
public function getAttributeValue($key)
{
    $value = parent::getAttributeValue($key);

    return is_string($value) ? trim($value) : $value;
}
0 likes
7 replies
bugsysha's avatar

Is there a way I can trim the original values before Laravel captures them?

Laravel already trims the input. You can verify it by going to \App\Http\Kernel and in $middleware property you should see \App\Http\Middleware\TrimStrings::class.

ale1981's avatar

Hi @bugsysha, I am aware of the TrimStrings class, however this trims the value before inserting to the DB, I need the opposite, trim the value when querying the DB.

bugsysha's avatar

Then create a command that will trim all problematic records in the database. I'm suggesting a command cause then you can use it as much as you need until you resolve all your issues.

ale1981's avatar

Trimming the data in the database is not a solution as the data can be altered in a different application which would then just add the whitespace again.

I need a solution that alters the data once Laravel retrieves it and works with the dirty methods.

bugsysha's avatar

That way you are trying to find a cure for the consequence, not for the root cause of the problem.

ale1981's avatar

I am sure I have already mentioned that I can't amend the database field type from char, otherwise that would have been the obvious solution.

ale1981's avatar
ale1981
OP
Best Answer
Level 3

If anybody else wants to achieve this where they can't control the data entered in to the application or the database column types used then I managed to do it by overriding this method on the model and using trim on the attributes. I am yet to come across any issues.

/**
 * Set the array of model attributes. No checking is done.
 *
 * @param  array  $attributes
 * @param  bool  $sync
 * @return $this
 */
public function setRawAttributes(array $attributes, $sync = false)
{
    $this->attributes = collect($attributes)->map(function ($item, $key) {
        return is_string($item) ? trim($item) : $item;
    })->toArray();

    if ($sync) {
        $this->syncOriginal();
    }

    $this->classCastCache = [];

    return $this;
}

Please or to participate in this conversation.