Laravel attribute casting

Viewed 3809

Here all values of metakey and metavalue are string type.hence price 200 and 100 both are string too. I want to filter users within minimum and maximum price.But i am struggling to do so because 200 and 100 both are string.

UsersTable

id|name

   1|xx

UserMeta table

id | user_id | metaKey | metavalue

  1 | 1        | city     | kolkata

  2 |2         |city      | london

  3 |8         |city      |london

  4 |1         |price     |200

   5|8         |price     |100

what I tried:

return User::whereHas('UserMeta', function ($query) use ($value) {
    $query->where('meta_key', 'price')
          ->where('meta_value','< =', intval($value));
});
3 Answers

Try this method otherwise You need to cast attributes in Eloquent by adding a protected $casts array to your model.

return User::whereHas('UserMeta', function ($query) use ($value) {
$query->where('meta_key', 'price')
      ->where('meta_value','< =', (int)$value);
});

Use builtin type casting

class User extends Model
{
   /**
   * The attributes that should be cast to native types.
   *
   * @var array
   */
   protected $casts = [
       'meta_key' => 'int',
       'meta_value' => 'int',
   ];
}

It will automatically convert them to integers. Read more here

You can also use eloquent mutators and accessors to convert them into int like this:

public function setMetaValueAttribute($value)
{
   if($this->attributes['meta_key'] == 'price'){
    $this->attributes['meta_value'] = (int)$value;
   }

}

Use the DB facade.

<?php
$data = DB::table('UserMeta')
            ->select(DB::raw("min(cast(metavalue as unsigned)) as 'min_value',max(cast(metavalue as unsigned)) as 'max_value'"))
            ->where('metaKey','=','price')
            ->get()[0];

$min_value = $data->min_value;
$max_value = $data->max_value;

$user_meta = DB::select("
                   select * 
                   from UserMeta
                   where cast(metavalue as unsigned) >= ". $min_value . " and cast(metavalue as unsigned) <= ". $max_value
                );
echo "<pre>";
var_dump($user_meta);
Related