Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zizi_ove's avatar

Query builder Avg method, problem with float numbers

Trying to create a 5-star rating system in Laravel. a star rate is a float number in the range [1 to 5] and it stores successfully in the database. migration file for rates table in database. ( I've set data type of star column as float)

    public function up()
    {
        Schema::create('rates', function (Blueprint $table) {
            $table->id();
            $table->morphs('rateble');     //creates rateable_id  and  rateable_type

            $table->foreignId('user_id')->nullable()
			->constrained()
			->onUpdate('cascade')
			->onDelete('set null');

            $table->float('star',2, 1);    //star number is from 0 to 5
            $table->timestamps();
        });
    }

Then for averaging the rating for a specific product, I am using this query:

    public function scopeAverageRate($query, $type, $id)
    {
        return $query->where('rateble_type', $type)
                     ->where('rateble_id', $id)
                     ->avg('star');
    }

The problem is, it seems that the avg() method cast the result to integer! Is there any way to set this function to work with the float numbers?

e.g. assume there is only one rate for a specific product that equals "0.5" stars then the average rating is "0" instead of "0.5" !

How can I solve this problem?

Thank you in advance,

0 likes
3 replies
zizi_ove's avatar

@jlrdw Thank you for your suggestion, but I think it can not help to solve the problem. maybe I'm wrong. could you please explain more how it could be used in avg() query?

Thanks,

zizi_ove's avatar

The problem is solved by using a raw query instead of avg() method:

        return $query->where('rateble_type', $type)
                     ->where('rateble_id', $id)
                     ->selectRaw('CAST(AVG(star) AS DECIMAL(2,1)) AS star_avg')->first()->star_avg;

hope it helps someone else.

Please or to participate in this conversation.