laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.68k stars 11.05k forks source link

Error trying to add attributes for serialization with Eloquent #42041

Closed lucasvmds closed 2 years ago

lucasvmds commented 2 years ago

Description:

When trying to add attributes for serialization as described in the documentation (Appending Values To JSON) an error is displayed: image

But to work I had to implement the method shown in the error. In this case would it be a problem with the framework or with the documentation?

Steps To Reproduce:

Code that generates the error:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Casts\Age;
use App\Models\Gender;
use Illuminate\Database\Eloquent\Casts\Attribute;

class Guest extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'custom_recipient' => 'boolean',
        'birth' => Age::class,
    ];

    protected $hidden = [
        'gender_id',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['gender'];

    protected function gender()
    {
        return new Attribute(
            get: fn () => 'yes',
        );
    }
}

Code that works:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Casts\Age;
use App\Models\Gender;

class Guest extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'custom_recipient' => 'boolean',
        'birth' => Age::class,
    ];

    protected $hidden = [
        'gender_id',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['gender'];

    /**
     * Retorna o gênero do visitante
     * 
     * @return string
     */
    protected function getGenderAttribute()
    {
       return $this->gender()->get()->first()->gender;
    }

    /**
     * Relacionamento com a tabela genders
     */
    protected function gender()
    {
        return $this->belongsTo(Gender::class);
    }
}
driesvints commented 2 years ago

You're not adding the Illuminate\Database\Eloquent\Casts\Attribute as a return type to your gender method. That's shown in the docs.