6

I have a Laravel Models that return string value instead of integer in my staging server. I decided to cast attribute's values to get always the integer value.

I report my Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class PressReviewPreset extends Model
{
    /**
     *  Use soft delete
     */
    use SoftDeletes;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'pr_preset';

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
    */
    protected $dates = ['deleted_at'];

    /**
     * The attributes that should be casted to native types.
     *
     * @var array
    */
    protected $casts = [
        'id' => 'integer',
        'user_id' => 'integer',
        'is_default' => 'integer',
    ];

    /**
     * The database field "updated_at" of table with a custom name
     * @var string
     */
    const UPDATED_AT = 'last_update';

    /*
    |---------------------------|
    |   Aliases for attribute   |
    |---------------------------|
    */

    // Id
    public function getIdAttribute()
    {
        return $this->attributes['id'];
    }
    public function setIdAttribute($id)
    {
        $this->attributes['id'] = $id;
    }

    // UserId
    public function getUserIdAttribute()
    {
        return $this->attributes['user_id'];
    }
    public function setUserIdAttribute($user_id)
    {
        $this->attributes['user_id'] = $user_id;
    }

    // Default
    public function getDefaultAttribute()
    {
        return $this->attributes['is_default'];
    }
    public function setDefaultAttribute($is_default)
    {
        $this->attributes['is_default'] = $is_default;
    }

    // ...

}

When I call attributes in my macbook's artisan tinker I get this results:

>>> $p = App\Models\PressReviewPreset::first()
=> App\Models\PressReviewPreset {#810
     id: 41,
     user_id: 391,
     name: "DEMO",
     is_default: 1,
     last_update: "2017-03-10 14:32:39",
     created_at: "2017-03-10 14:27:24",
     deleted_at: null,
   }
>>> $p->id
=> 41
>>> $p->user_id
=> 391
>>> $p->userId
=> 391
>>> $p->is_default
=> 1
>>> $p->default
=> 1

All values are correctly integer.

But if I call same attributes on my staging server I get this results:

>>> $p = App\Models\PressReviewPreset::first()
=> App\Models\PressReviewPreset {#810
     id: "41",
     user_id: "391",
     name: "DEMO",
     is_default: "1",
     last_update: "2017-03-10 14:32:39",
     created_at: "2017-03-10 14:27:24",
     deleted_at: null,
   }
>>> $p->id
=> "41"
>>> $p->user_id
=> "391"
>>> $p->userId
=> "391"
>>> $p->is_default
=> 1
>>> $p->default
=> "1"

Why user_id is not correctly casted to integer?

Am I doing somethings wrong?

Thanks in advance!

Tenaciousd93
  • 3,438
  • 4
  • 33
  • 56
  • Follow this thread http://stackoverflow.com/questions/20079320/php-pdo-mysql-how-do-i-return-integer-and-numeric-columns-from-mysql-as-int – EddyTheDove Mar 16 '17 at 07:58
  • @EddyTheDove I'm curious as I've confronted the same issue in the past... although the thread you linked may detail the source of the problem, shouldn't Laravel's casting functionality ensure the values are typecast properly when the model is populated? – alaric Mar 16 '17 at 08:28
  • Tenacious, as a work-around, have you tried casting the values within the setXxxAttribute functions instead? – alaric Mar 16 '17 at 08:34
  • @Eddy: I have already installed: `PDO support => enabled; PDO drivers => mysql; pdo_mysql; PDO Driver for MySQL => enabled; Client API version => 5.5.46;` @Alaric: Yes, my work-around was set different name for getter/setter attributes (See `is_default` => `set/getDefaultAttribute()` )... – Tenaciousd93 Mar 16 '17 at 13:33

1 Answers1

2

What about in your attributes, you cast it again ?

public function getIdAttribute()
{
    return (int) $this->attributes['id'];
}

Any luck?

EddyTheDove
  • 12,979
  • 2
  • 37
  • 45